instancancetype

来源:互联网 发布:mac chm阅读器 编辑:程序博客网 时间:2024/05/21 17:56
instancetype 的解释可以参考这两处:

http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id

http://blog.eddie.com.tw/2013/12/16/id-and-instancetype/


什么是instancetype?

"instancetype is a contextual keyword that is only permitted in the result type of an Objective-C method",instancetype是个关键字,告诉编译器返回值的类型,让编译器可以在编译阶段就可以判断程序是否有问题。

instancetype只能作为返回值,不能作为参数。



Apple上是这样讲的:

“In your code, replace occurrences of id as a return value with instancetype where appropriate. This is typically the case for init methods and class factory methods. Even though the compiler automatically converts methods that begin with “alloc,” “init,” or “new” and have a return type of id to return instancetype, it doesn’t convert other methods. Objective-C convention is to write instancetype explicitly for all methods.”

大致意思是说:在合适的场合,用instancetype来替换id,特别是在init方法和类工厂方法中。虽然编译器自动的把以“alloc”,“init”,“new”开头的方法的返回值从id类型转换成instancetype,但是编译器并不转换其他的方法。

@interface Foo:NSObject - (id)initWithBar:(NSInteger)bar; // initializer + (id)fooWithBar:(NSInteger)bar;  // class factory @end

对于类工厂方法,应该总是使用instancetype。编译器并不自动的把id转换成instancetype类型。id是任何对象,但如果使用instancetype的话,编译器就会知道方法返回值的类型。

例如,在Mac OS X中,[[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData] 会产生“Multiple methods named 'writeData:' found with mismatched result, parameter type or attributes.”的错误。原因是NSFileHandle 和 NSURLHandle都提供了writeData:的方法。由于[NSFileHandle fileHandleWithStandardOutput]返回的是id类型,编译器就不能确定到底是哪一个类的writeData:方法被调用。

如果想不报错,可以这样使用:

[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData];

或者:

NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];[fileHandle writeData:formattedData];

当然,更好的解决方法是声明 fileHandleWithStandardOutput 返回 instancetype 类型。

(Note:在iOS中,上面的例子不会产生错误,因为只用NSFileHandle用writeData:的方法)

至于初始化方法,它更复杂,当如下写的时候:

- (id)initWithBar:(NSInteger)bar
编译器会用如下的方法来代替:

- (instancetype)initWithBar:(NSInteger)bar

使用instancetype有什么好处呢?举个栗子:

建立两个类,Animal继承自NSObject,Human继承自Animal,Animal定义一个类方法。

@interface Animal : NSObject+ (id)animal;@end@interface Human : Animal- (void)speak;@end
@implementation Animal+ (id)animal{    return [[self alloc] init];}@end@implementation Human- (void)speak{    NSLog(@"speak");}@end

如果这样写:

[[Animal animal] speak];

在编译阶段没有问题,但是执行之后就crash。这是因为+ (id)animal方法,返回值是id,编译器在编译阶段不知道它确切的类型,所以就只好先放过了,但是在执行阶段就crash了。

把id换成instancetype,如下:

@interface Animal : NSObject+ (instancetype)animal;@end
+ (instancetype)animal{    return [[self alloc] init];}@end

编译器会提示错误:



0 0
原创粉丝点击