Objective-C特性之instancetype

如果一个方法将返回本类的一个实例对象, 那么推荐使用instancetype关键字来作为它的返回类型. 这些方法包括alloc, init以及类的工厂方法.

在合适的地方, 用instancetype代替id可以提高Objective-C代码的类型安全性. 举个例子, 考虑下面的代码:

@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]; // 报错
    y = [[MyObject factoryMethodB] count]; // 不报错
}

因为+factoryMethodA的返回值类型为instancetype, 所以[MyObject factoryMethodA]返回一个MyObject类的对象. 而MyObject类并没有定义-count方法, 所以编译器在x那一行会报错, 有助于我们在开发阶段就发现错误并且进行修正.

然而, +factoryMethodB的返回值类型为id, 编译器就不能给出任何警告或者错误信息, 因为id修饰的对象可能是任意类的实例, -count方法可能就存在于某个类中.

为了确保instancetype工厂方法在子类中也能有正确的行为, 一定要用[self class]来给对象分配空间, 而不要直接使用类名, 这可以确保编译器能正确推断出子类的类型. 举个例子, 定义一个MyObject的子类:

@interface MyObjectSubclass : MyObject

@end

@implementation MyObjectSubclass

@end

- (void)doSomething {
    NSString *aString = [MyObjectSubclass factoryMethodA]; // 报警告, 类型不匹配
}

在例子中, 编译器可正确推断出[MyObjectSubclass factoryMethodA]返回一个MyObjectSubclass类的对象, 而不是父类MyObject.

注意, 只有作为返回类型时, instancetype才可替换id, 而不是所有的情况, 和id不同, instancetype关键字只能作为返回类型.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值