id、instancetype
id
一个类的实例的指针,万能指针
申明
typedef struct objc_object *id;
instancetype
使用instancetype关键字作为方法的返回值代表返回当前类或者当前类的子类的实例.相应的方法有alloc,init
以及便利构造方法
在恰当的地方使用instancetype取代id可以提高类型安全.例如,下面的代码
@interface MyObject : NSObject
+ (instancetype)factoryMethodA;
+ (id)factoryMethodB;
@end
@implementation MyObject
+ (instancetype)factoryMethodA { return [[[self class] alloc] init]; }
+ (id)factoryMethodB { return [[[self class] alloc] init]; }
@end
void doSomething() {
NSUInteger x, y;
x = [[MyObject factoryMethodA] count]; // 返回对象是MyObject类型
y = [[MyObject factoryMethodB] count]; // 返回对象是id类型
}
instancetype的返回类型就是(MyObject *),因为MyObject没有 -count这个方法,所以编译器给出了一个警告:
main.m: ’MyObject’ may not respond to ‘count’
然后另一个id类型的却没有任何警告,上面已经说明id可以指向任意类型,所以在没有执行这段代码之前系统不知道该对象是否拥有-count这个方法.
再看另一个例子:
@interface MyObjectSubclass : MyObject
@end
void doSomethingElse() {
NSString *aString = [MyObjectSubclass factoryMethodA];
}
这个时候编译器给出了警告:
main.m: Incompatible pointer types initializing ’NSString *’ with an expression of type ’MyObjectSubclass *’
直接指明我们的类型不匹配,所以我们应该使用instancetype
比如下面例子
@interface MyObject
- (id)myFactoryMethod;
@end
应该写成这样
@interface MyObject
- (instancetype)myFactoryMethod;
@end
总结
- id 可以作为方法参数传递 intancetype 不能
- id 可以去接受对象 instancetype不能
- 在自定义初始化或者便利构造方法中尽量使用instancetype作为返回值类型,保证类型安全
转载:http://archerzz.ninja/ios/id-instancetype.html