OC语言day04-10instancetype(实例类型)和id的区别

pragma mark instancetype(实例类型)和id的区别

pragma mark 概念

/**
 instance type 实例类型
 
 // instancetype == id == 万能指针 == 指向一个对象
 // id 在编译的时候 不能判断对象的真实类型
 // instancetype 在编译的时候 可以判断对象的真实类型
 
 // id 和 instancetype
 // 除了 一个在编译时 不知道真实类型, 一个在编译时 知道真实类型以外 \
 // 还有 id 可以用来定义变量, 可以作为返回值, 可以作为形参 \
 // instancetype 只能用于作为返回值
 
 // 注意: 以后 但凡自定义构造方法, 返回值尽量使用instancetype,不要使用id
 
 */

pragma mark 代码

#import 
#pragma mark 类
#import "Person.h"

#pragma mark main函数
int main(int argc, const char * argv[])
{
//    Person *p = [[Person alloc]init];
//    [p setAge:22];
    
    // 如果init方法的返回值 是 instance type, 那么将返回值 返回 一个其他的对象 会报一个警告
    // 如果是在以前, init的返回值是id, 那么将init返回的对象地址赋值 给其他对象是不会报错的
//    NSString *str = [[Person alloc]init];
#warning id用来定义变量
    id p = [[Person alloc]init];
#warning instancetype 不能用来定义变量
    instancetype p1 = [[Person alloc]init];
#warning 错误解释
    // 1.编译的时候不会报错, 因为编译的时候 不会去检查str的真实类型
    // 2.但是运行的时候 会去检查str的真实类型, 而str的真实类型是Person, 但是Person 里面没有length这个方法 所以程序直接崩掉
    /*
     [Person length]: unrecognized selector sent to instance 0x100102490'
     */
//    NSUInteger length = [str length];
//    NSLog(@"length %lu",length);
    return 0;
}

Person.h //人类
#import 

@interface Person : NSObject

@property int age;

#warning id作为形参
- (void)test:(id)obj1;
#warning instancetype 不能作为形参
- (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 = 22;
    }
    return self;
}

@end

你可能感兴趣的:(OC语言day04-10instancetype(实例类型)和id的区别)