// Person.h #import <Foundation/Foundation.h> @interface Person : NSObject @property int age; - (void)test:(id)obj1; //编译不报错 - (void)demo:(instancetype)obj2; //不能定义变量,不能定义形参数 @end
// // Person.m #import "Person.h" @implementation Person // instancetype == id == 万能指针 == 指向一个对象 // id在编译的时候不能判断对象的真实类型 // instancetype在编译的时候可以判断对象的真实类型 // id和instancetype除了一个在编译时不知道真实类型, 一个在编译时知道真实类型以外, 还有一个区别 // id可以用来定义变量, 可以作为返回值, 可以作为形参 // instancetype只能用于作为返回值 // 注意: 以后但凡自定义构造方法, 返回值尽量使用instancetype, 不要使用id - (instancetype)init //- (id)init { if (self = [super init]) { _age = 5; } return self; } @end
// // main.m // instancetype和id的区别 #import <Foundation/Foundation.h> #import "Person.h" int main(int argc, const char * argv[]) { Person *p11 =[[Person alloc] init]; [p11 setAge:99]; // 如果init方法的返回值是instancetype, 那么将返回值赋值给一个其它的对象会报一个警告,赋值给NSString不会报错 // 如果是在以前, init的返回值是id, 那么将init返回的对象地址赋值给其它对象是不会报错的 NSString *str = [[Person alloc] init];//运行时报错,不能是NSString类型 id p = [[Person alloc] init]; instancetype p1 = [[Person alloc] init];//编译时检查数据类型,instancetype不能定义变量和定义形参, NSUInteger length = [str length]; NSLog(@"length = %lu", length); return 0; }