代码改变世界

iOS 方法修饰符

  v2m  阅读(1451)  评论(0编辑  收藏  举报

 一、NS_DESIGNATED_INITIALIZER

     

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

 

  参考1对之的说明为

 

1
2
3
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
2
3
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/

编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示