我们在 XCode 6 中引入了这个新宏:NS_DESIGNATED_INITIALIZER
我在网上搜索过,但实际上找不到任何关于如何使用它的好文档.
在语法上,我们可以像这样使用它:
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
但是用这个宏标记一个初始化器可能有什么好处,以及我们在使用这个宏时应该注意什么?
我主要对这个宏的用例感兴趣.任何链接/文档将不胜感激.
NS_DESIGNATED_INITIALIZER
的使用在 http://useyourloaf.com/blog/2014/08/19/xcode-6-objective-c-modernization.html:p><块引用>
指定的初始化器保证对象被完全初始化通过向超类发送初始化消息.这实现细节对类的用户来说变得很重要,当他们将其子类化.指定初始化器的详细规则:
例如,如果你的界面是
@interface MyClass : NSObject@property(copy, nonatomic) NSString *name;-(instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;-(实例类型)初始化;@结尾
然后编译器检查(方便)初始化器 init
是否调用(指定的)初始化程序 initWithName:
,所以这会导致警告:
-(instancetype)init{self = [超级初始化];回归自我;}
这样就可以了:
-(instancetype)init{self = [self initWithName:@""];回归自我;}
在 Swift 中,关于指定初始化器和便利初始化器的规则更加严格,如果你混合使用 Objective-C 和 Swift 代码,标记指定的 Objective-C 初始化器有助于编译器执行规则.
例如,这个 Swift 子类会导致编译器错误:
类 SwClass: MyClass {var foo : 字符串初始化(富:字符串){self.foo = foo超级初始化()}}
这样就可以了:
类 SwClass: MyClass {var foo : 字符串初始化(富:字符串){self.foo = foo超级初始化(名称:")}}
We have this new macro being introduced in XCode 6 : NS_DESIGNATED_INITIALIZER
I searched on the net, but couldn't really find any good documentation as to how to use this.
Syntactically, we can use it like :
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
But what are the possible advantages of marking an initializer with this macro, and also what are the things we should be looking at when using this ?
I am mainly interested in the use cases of this macro. Any links / documentation would be appreciated.
The use of NS_DESIGNATED_INITIALIZER
is nicely explained in http://useyourloaf.com/blog/2014/08/19/xcode-6-objective-c-modernization.html:
The designated initializer guarantees the object is fully initialised by sending an initialization message to the superclass. The implementation detail becomes important to a user of the class when they subclass it. The rules for designated initializers in detail:
- A designated initializer must call (via super) a designated initializer of the superclass. Where NSObject is the superclass this is just [super init].
- Any convenience initializer must call another initializer in the class - which eventually leads to a designated initializer.
- A class with designated initializers must implement all of the designated initializers of the superclass.
As an example, if your interface is
@interface MyClass : NSObject
@property(copy, nonatomic) NSString *name;
-(instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
-(instancetype)init;
@end
then the compiler checks if the (convenience) initializer init
calls
the (designated) initializer initWithName:
, so this would cause a warning:
-(instancetype)init
{
self = [super init];
return self;
}
and this would be OK:
-(instancetype)init
{
self = [self initWithName:@""];
return self;
}
In Swift the rules about designated and convenience initializers are even more strict, and if you mix Objective-C and Swift code, marking the designated Objective-C initializers helps the compiler to enforce the rules.
For example, this Swift subclass would cause an compiler error:
class SwClass: MyClass {
var foo : String
init(foo : String) {
self.foo = foo
super.init()
}
}
and this would be OK:
class SwClass: MyClass {
var foo : String
init(foo : String) {
self.foo = foo
super.init(name: "")
}
}
这篇关于iOS 指定初始化器:使用 NS_DESIGNATED_INITIALIZER的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!