美文网首页
@property中有哪些属性关键字?/ @property 后

@property中有哪些属性关键字?/ @property 后

作者: Zorin | 来源:发表于2020-07-08 17:30 被阅读0次

    一、 属性可以拥有的特质分为四类:

    1. 原子性--- nonatomic 特质

    在默认情况下,由编译器合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备 nonatomic 特质,则不使用互斥锁(atomic 的底层实现,老版本是自旋锁,iOS10开始是互斥锁--spinlock底层实现改变了。)。请注意,尽管没有名为“atomic”的特质(如果某属性不具备 nonatomic 特质,那它就是“原子的” ( atomic) ),但是仍然可以在属性特质中写明这一点,编译器不会报错。若是自己定义存取方法,那么就应该遵从与属性特质相符的原子性。

    1. 读/写权限---readwrite(读写)、readonly (只读)
    2. 内存管理语义---assign、strong、 weak、unsafe_unretained、copy
    3. 方法名---getter=<name> 、setter=<name>

    getter=<name>的样式:

     @property (nonatomic, getter=isOn) BOOL on;
    

    setter=这种不常用,也不推荐使用。故不在这里给出写法。)

    setter=<name>一般用在特殊的情境下,比如:

    在数据反序列化、转模型的过程中,服务器返回的字段如果以 init 开头,所以你需要定义一个 init 开头的属性,但默认生成的settergetter 方法也会以 init 开头,而编译器会把所有以 init 开头的方法当成初始化方法,而初始化方法只能返回 self 类型,因此编译器会报错。

    这时你就可以使用下面的方式来避免编译器报错:

    @property(nonatomic, strong, getter=p_initBy, setter=setP_initBy:)NSString *initBy;
    

    另外也可以用关键字进行特殊说明,来避免编译器报错:

    @property(nonatomic, readwrite, copy, null_resettable) NSString *initBy;
    - (NSString *)initBy __attribute__((objc_method_family(none)));
    

    二、不常用的:

    nonnull,null_resettable,nullable


    附加

    关于原子行 atomic

    注意:很多人会认为如果属性具备 nonatomic 特质,则不使用 “同步锁”。其实在属性设置方法中使用的是互斥锁(atomic 的底层实现,老版本是自旋锁,iOS10开始是互斥锁--spinlock底层实现改变了。)

    相关代码如下:

    static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
    {
       if (offset == 0) {
           object_setClass(self, newValue);
           return;
       }
    
       id oldValue;
       id *slot = (id*) ((char*)self + offset);
    
       if (copy) {
           newValue = [newValue copyWithZone:nil];
       } else if (mutableCopy) {
           newValue = [newValue mutableCopyWithZone:nil];
       } else {
           if (*slot == newValue) return;
           newValue = objc_retain(newValue);
       }
    
       if (!atomic) {
           oldValue = *slot;
           *slot = newValue;
       } else {
           spinlock_t& slotlock = PropertyLocks[slot];
           slotlock.lock();
           oldValue = *slot;
           *slot = newValue;        
           slotlock.unlock();
       }
    
       objc_release(oldValue);
    }
    
    void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, signed char shouldCopy) 
    {
       bool copy = (shouldCopy && shouldCopy != MUTABLE_COPY);
       bool mutableCopy = (shouldCopy == MUTABLE_COPY);
       reallySetProperty(self, _cmd, newValue, offset, atomic, copy, mutableCopy);
    }
    

    相关文章

      网友评论

          本文标题:@property中有哪些属性关键字?/ @property 后

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