属性@property探索

  1. @property用来定义变量的属性,定义的变量会自动声明变量,自动生成setter方法和getter方法,便于变量的操作,常用的修饰词是nonatomic,strong,readwrite等。

  2. 通过clang的方法查看@property生成的变量和方法如下:
    写一个属性

@interface Property ()

@property(nonatomic, copy) NSString * myName;

@end

执行clang命令

clang -rewrite-objc Property.m

得到.cpp文件,其中变量和方法的部分如下
我们创建的类为MyProperty,MyProperty_IMPL为类的实现,可以看到系统自动生成的变量_myName

typedef struct objc_object MyProperty;
typedef struct {} _objc_exc_MyProperty;
#endif

extern "C" unsigned long OBJC_IVAR_$_MyProperty$_myName;
struct MyProperty_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    NSString *_myName;
};
static NSString * _I_MyProperty_myName(MyProperty * self, SEL _cmd) { return (*(NSString **)((char *)self + OBJC_IVAR_$_MyProperty$_myName)); }
extern "C" __declspec(dllimport) void objc_setProperty (id, SEL, long, id, bool, bool);

static void _I_MyProperty_setMyName_(MyProperty * self, SEL _cmd, NSString *myName) { objc_setProperty (self, _cmd, __OFFSETOFIVAR__(struct MyProperty, _myName), (id)myName, 0, 1); }

将自动生成的ivar和method加入列表

static struct /*_ivar_list_t*/ {
    unsigned int entsize;  // sizeof(struct _prop_t)
    unsigned int count;
    struct _ivar_t ivar_list[1];
} _OBJC_$_INSTANCE_VARIABLES_MyProperty __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_ivar_t),
    1,
    {{(unsigned long int *)&OBJC_IVAR_$_MyProperty$_myName, "_myName", "@\"NSString\"", 3, 8}}
};

static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)
    unsigned int method_count;
    struct _objc_method method_list[4];
} _OBJC_$_INSTANCE_METHODS_MyProperty __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    4,
    {{(struct objc_selector *)"myName", "@16@0:8", (void *)_I_MyProperty_myName},
    {(struct objc_selector *)"setMyName:", "v24@0:8@16", (void *)_I_MyProperty_setMyName_},
    {(struct objc_selector *)"myName", "@16@0:8", (void *)_I_MyProperty_myName},
    {(struct objc_selector *)"setMyName:", "v24@0:8@16", (void *)_I_MyProperty_setMyName_}}
};

从.cpp文件可以看到,@property会在编译阶段自动生成ivar成员变量"_myName"、getter方法"myName"和setter方法"setMyName:"

{
    NSString *_myName;
}
- (void)setMyName:(NSString *)myName;
- (NSString *)myName;
  1. nonatomic是非原子性,修饰的变量不会对setter方法加锁,属于非线程安全,但是运行速度快,适合用于移动设备上;
    atomic是原子性,对setter方法加锁,具有线程安全,但是会消耗大量资源
    系统默认修饰是atomic,所以在声明变量时需要指定nonatomic

  2. assign修饰整形变量
    strong是强引用
    copy是复制属性
    weak是弱引用,避免循环引用会使用weak

  3. readwrite是可读可写,自动生成setter和getter方法
    readonly为只读状态,只会生成getter方法
    调用属性的setter方法会触发键值观测

_myName = "ella";         //该操作是赋值操作,不会触发键值观测
self.myName = "ella";    //该操作调用的是setter方法,会触发键值观测

你可能感兴趣的:(属性@property探索)