美文网首页
Objective-C中的一些修饰符

Objective-C中的一些修饰符

作者: 宇文袥 | 来源:发表于2019-04-08 15:49 被阅读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
    

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

    • typedef定义的类型的nullability特性通常依赖于上下文,即使是在Audited Regions中,也不能假定它为nonnull。
    • 复杂的指针类型(如id *)必须显示去指定是nonnull还是nullable。例如,指定一个指向nullable对象的nonnull指针,可以使用”__nullable id * __nonnull”。
    • 我们经常使用的NSError **通常是被假定为一个指向nullable NSError对象的nullable指针。

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

    相关文章

      网友评论

          本文标题:Objective-C中的一些修饰符

          本文链接:https://www.haomeiwen.com/subject/ccauiqtx.html