Objective-C中的一些修饰符

2019-04-08  本文已影响0人  宇文袥

__kindof

__kindof 这修饰符很实用的,解决了一个长期以来的小痛点,拿原来的 UITableView 的这个方法来说:

- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier;

使用时前面基本会使用 UITableViewCell 子类型的指针来接收返回值,所以这个 API 为了让开发者不必每次都蛋疼的写显式强转,把返回值定义成了 id 类型,而这个 API 实际上的意思是返回一个 UITableViewCell 或 UITableViewCell 子类的实例,于是新的 __kindof 关键字解决了这个问题:

- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

既明确表明了返回值,又让使用者不必写强转。再举个带泛型的例子,UIView 的 subviews 属性被修改成了:

@property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;

这样,写下面的代码时就没有任何警告了:

UIButton *button = view.subviews.lastObject;

nullability annotations(空性修饰符)

苹果在Xcode 6.3引入的一个Objective-C的新特性
nonnull:非空
nullable:可空
null_resettable: setter nullable,但是 getter nonnull(注意:如果使用null_resettable,必须 重写get方法或者set方法,处理传递的值为空的情况)

最直观例子就是 UIViewController 中的 view 属性:
@property (null_resettable, nonatomic, strong) UIView *view;

__null_unspecified:不能确定是否为空
基本用法

//三种使用方式都可以
@property (nonatomic, copy, nonnull) NSString *name;

@property (nonatomic, copy) NSString * _Nonnull name;

@property (nonatomic, copy) NSString * __nonnull name;

//补充(不适用于assign属性,因为它是专门用来修饰指针的)
@property (nonatomic, assign) NSUInteger age;

//补充(用下面宏包裹起来的属性全部都具nonnull特征,当然,如果其中某个属性你不希望有这个特征,也可以自己定义,比如加个nullable)
//在NS_ASSUME_NONNULL_BEGIN和NS_ASSUME_NONNULL_END之间,定义的所有对象属性和方法默认都是nonnull

//也可以在定义方法的时候使用
//返回值和参数都不能为空
- (nonnull NSString *)test:(nonnull NSString *)name;
//同上
- (NSString * _Nonnull)test1:(NSString * _Nonnull)name;


===========================null_resettable============================
@property (nonatomic, copy, null_resettable) NSString *name;

- (void)setName:(NSString *)name {
    if (name == nil) {
        name = @"XXX";
    }
    _name = name;
}

- (NSString *)name {
    if (_name == nil) {
        _name = @"XXX";
    }
    return _name;
}

在Swift中可以使用!和?来表示一个对象是optional的还是non-optional,如button?和button!。而在Objective-C中则没有这一区分。这个简版的 Optional ,没有 Swift 中 ? 和 ! 语法糖的支持,在 Objective-C 中就显得非常啰嗦,所以为了防止写一大堆 nonnull,Foundation 还提供了一对宏,包在里面的对象默认加 nonnull 修饰符,只需要把 nullable 的指出来就行,黑话叫 Audited Regions:

NS_ASSUME_NONNULL_BEGIN
@interface Sark : NSObject
@property (nonatomic, copy, nullable) NSString *workingCompany;
@property (nonatomic, copy) NSArray *friends;
- (nullable NSString *)gayFriend;
@end
NS_ASSUME_NONNULL_END

不过,为了安全起见,苹果还制定了几条规则:

参考文章:
2015 Objective-C 新特性
OC

上一篇下一篇

猜你喜欢

热点阅读