美文网首页重拾iOS
重拾iOS-@property

重拾iOS-@property

作者: Jack1105 | 来源:发表于2020-06-16 17:38 被阅读0次

    注意在ARC环境下:

    1、在类中

    @property的本质:

    @property = ivar(实例变量) + getter/setter方法声明 + getter/setter方法实现;
    

    当在类中使用@property声明属性时,无论是在.h中的还是在.m中,
    编译器会自动生成一个带下划线的实例变量 + 对应的getter/setter方法的声明 + 对应的getter/setter方法的实现;

    例如:

    @interface Person : NSObject
    
    @property (nonatomic, copy) NSString *name;
    
    @end
    

    此时,会给Person类的.h中默认添加一个名为_name的成员变量,setName和name:两个方法(getter/setter)的声明,如:

    @interface Person : NSObject
    {
        NSString *_name;
    }
    - (void)setName:(NSString *)name;
    - (NSString *)name;
    
    @end
    

    并且在Person类的.m中添加setName和name:两个方法(set/get)的实现,如:

    - (void)setName:(NSString *)name{
        _name = name;
    }
    - (NSString *)name{
        return _name;
    }
    

    2、在分类中

    @property的本质:

    @property = getter/setter方法声明;
    

    可以发现,当我们在分类中使用@property声明属性时,只是生成了getter/setter方法的声明,并不会自动生成ivar(实例变量) 和 getter/setter方法的实现。

    例如:

    @interface Person (test)
    
    @property (nonatomic, copy) NSString *name;
    
    @end
    

    此时,只是在分类的.h中自动生成了setName和name:两个方法(set/get)的声明,如:

    @interface Person (test)
    
    - (void)setName:(NSString *)name;
    - (NSString *)name;
    
    @end
    

    并且,在.m中有会提示:

    提示需要提供setter/getter方法的实现;

    如果,不提供setter/getter方法的实现,在使用是会报错unrecognized selector,
    如下:


    所以,一般我们会通过runtime添加关联对象,来间接的实现给分类添加属性。如下:

    #import "Person+test.h"
    #import <objc/runtime.h>
    
    @implementation Person (test)
    
    - (NSString *)name {
        return objc_getAssociatedObject(self, @selector(name));
    }
    - (void)setName:(NSString *)name {
        objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    @end
    

    分类(Category)具体的实现原理,这里暂不详细说明;

    相关文章

      网友评论

        本文标题:重拾iOS-@property

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