欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS 方法修饰符

程序员文章站 2022-07-15 08:02:58
...

 一、NS_DESIGNATED_INITIALIZER

     

  用来修饰init方法,被修饰的方法称为designated initializer;没有被这个修饰的init方法称为convenience initializer

 

  参考1对之的说明为

 

1.A designated initializer must call (via super) a designated initializer of the superclass. Where NSObject is the superclass this is just [super init].
2.Any convenience initializer must call another initializer in the class - which eventually leads to a designated initializer.
3.A class with designated initializers must implement all of the designated initializers of the superclass.

 

  解释下就是

1.designated initializer 必须调用父类的designated initializer (最终指向也会有警告)
2.convenience initializer最终必须指向一个designated initializer
3.有designated initializer的类必须实现父类的designated initializer方法 

 

  补充点

  1.继承性,当子类里面没有其他的init方法时,继承父类的designated initializer;如果子类有其他的init方法,则父类的 designated initializer 方法 都变成了  convenience initializer

 

  2.NSCoding 的 initWithCoder: 是一个 designated initializer方法

 

  3.参考2最后提出了一个疑问

 

@interface A : NSObject
 
- (instancetype)initDesignated NS_DESIGNATED_INITIALIZER;
- (instancetype)initUndesignated;
 
@end
 
@implementation A
 
- (instancetype)init
{
  return ([self initUndesignated]);
}
 
- (instancetype)initDesignated
{
  return (self = [super init]);
}
- (instancetype)initUndesignated
{
  return (self = [self initDesignated]);
}
 
@end
 
@interface B : A
 
- (instancetype)initDesignatedB NS_DESIGNATED_INITIALIZER;
- (instancetype)initUndesignatedB;
 
@end
 
@implementation B
 
- (instancetype)initDesignated
{
  return [self initUndesignatedB];
}
 
- (instancetype)initDesignatedB
{
  return (self = [super initDesignated]);
}
 
- (instancetype)initUndesignatedB
{
  return ([self initDesignated]);
}
 
@end 

  参考2疑问为什么 最后一个函数 initUndesignatedB 里面这样调用不会有警告,其实很好理解。

    1.因为self没有实现initUndesignated,所以会调用 super 的 initUndesignated方法

    2.super 的 initUndesignated 需要调用 initDesignated 方法

    3.子类实现了 initDesignated 方法,所以最终回调用到 self 的 initDesignated 方法

  这当然不会有什么问题了

 

 

二、NS_UNAVAILABLE  

  用来修饰所有的方法,表示这个类的这个方法是不可用的。

   一个很好的用法就是配合上面的 NS_DESIGNATED_INITIALIZER 修饰符。因为父类的 designated initializer 必须在子类实现,而如果子类只希望有另一种 designated initializer 存在,就可以把父类的 designated initializer 申明为 NS_UNAVAILABLE,这样就不用去实现,也避免出现多个init 方法。

 

三、NS_REQUIRES_SUPER

  用来修饰所有方法,表示子类override父类的方法时,必须在方法内部调用super的这个方法。

  如果子类真的不想去调用 super 用 NS_REQUIRES_SUPER 修饰的方法,又不想出现警告,那么可以用下面的方式处理

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-missing-super-calls"
方法实现
#pragma clang diagnostic pop

 

四、无修饰  

如果是init方法,那么这个init方法就是 convenience initializer。

 

 

参考:

1.http://useyourloaf.com/blog/xcode-6-objective-c-modernization/

2.https://yq.aliyun.com/articles/5847

3.http://blog.jobbole.com/65762/