正确使用NS_DESIGNATED_INITIALIZER
Posted zcube
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正确使用NS_DESIGNATED_INITIALIZER相关的知识,希望对你有一定的参考价值。
为什么会提到NS_DESIGNATED_INITIALIZER
最近在清理项目警告,遇到了“Method override for the designated initializer”的警告,全称为:
- Method override for the designated initializer of the superclass '-init' not found 或者
- Method override for the designated initializer of the superclass '-initWithNibName:bundle:' not found。
经排查是因为头文件中出现NS_DESIGNATED_INITIALIZER 声明的初始化方法,如下:
// .h
- (instancetype)initWithPurchaseService:(HTLPrepayPurchaseService *)service NS_DESIGNATED_INITIALIZER;
|
如果用了NS_DESIGNATED_INITIALIZER,那么警告中出现init还是initWithNibName或是其它,取决于你的继承的父类类型:
UIViewController
- Method override for the designated initializer of the superclass '-initWithNibName:bundle:' not found
- Method override for the designated initializer of the superclass '-initWithCoder:' not found
UIView
- Method override for the designated initializer of the superclass '-initWithFrame:' not found
- Method override for the designated initializer of the superclass '-initWithCoder:' not found
NSObject
-
Method override for the designated initializer of the superclass '-init' not found
正确使用NS_DESIGNATED_INITIALIZER
为什么要用NS_DESIGNATED_INITIALIZER
Objective-C 中主要通过NS_DESIGNATED_INITIALIZER
宏来实现指定构造器的。这里之所以要用这个宏,往往是想告诉调用者要用这个方法去初始化(构造)类对象。
怎样避免使用NS_DESIGNATED_INITIALIZER产生的警告
如果子类指定了新的初始化器,那么在这个初始化器内部必须调用父类的Designated Initializer。并且需要重写父类的Designated Initializer,将其指向子类新的初始化器。
如下:
// .h
- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
// .m
- (instancetype)init
return
[self initWithName:@
""
];
- (instancetype)initWithName:(NSString *)name
self = [super init];
if
(self)
// do something
return
self;
|
更好的做法
如果定义NS_DESIGNATED_INITIALIZER,大多是不想让调用者调用父类的初始化函数,只希望通过该类指定的初始化进行初始化,这时候就可以用NS_UNAVAILABLE宏。
如下:
// .h
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
|
如果调用者使用init 初始化,编译器就会给出一个编译错误。使用NS_UNAVAILABLE后,就不需要在.m中重写父类初始化函数了。如果要允许调用者使用init就需要在.m中重写父类的初始化函数,如上提到的,否则就会报警告。
避免使用new
如果使用new来创建对象的话,即使init被声明为NS_UNAVAILABLE,也不会收到编译器的警告和错误提示了。
参考链接
- http://www.starfelix.com/blog/2014/04/13/zheng-que-bian-xie-designated-initializerde-ji-ge-yuan-ze/
- http://stackoverflow.com/questions/26185239/ios-designated-initializers-using-ns-designated-initializer
- https://craftbeercraftcode.com/2014/12/28/better-brewing-with-ns_unavailable/
以上是关于正确使用NS_DESIGNATED_INITIALIZER的主要内容,如果未能解决你的问题,请参考以下文章
如何正确使用 Composer 安装 Laravel 扩展包
如何正确使用 Composer 安装 Laravel 扩展包