iOS属性关键字

  • @property

    相当于声明了setter和getter方法
 ivar + getter + setter

对应runtime底层的objc_property_t

struct property_t {
    const char *name;
    const char *attributes;
};

其中 attributes 本质是 objc_property_attribute_t
typedef struct {
    const char *name;           /**< The name of the attribute */
    const char *value;          /**< The value of the attribute (usually empty) */
} objc_property_attribute_t;

attributes具体内容包括类型 原子性  内存语义 实例变量

@property (nonatomic, strong) NSArray *array;

通过 property_getAttributes(property) 获取到 attributes,完成属性的定义,编译器会自动编写访问这些属性的所需方法,这个过程叫做自动合成(autosynthesis)

这个过程是在编译期中完成的,编译器中看不到对应的合成方法(synthesized method)源代码,除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。

@property (nonatomic, strong) id selectControl;

会生成两个实例变量,其名称分别为 _selectControl或者在类的实现代码里通过 @synthesize 语法来指定实例变量的名字.

@synthesize _ selectControl = selectControl;

添加属性的过程:
1、在var_list(成员变量列表)中添加一个成员变量的描述
2、在method_list(方法列表)中添加setter getter方法的描述
3、在prop_list属性列表中添加属性的描述

  • @synthesize 和 @dynamic

1、@synthesize 语义是系统会自动帮你生成setter和getter方法,然后生成一个对应的实例变量名

@property (nonatomic, strong) id selectControl;

//生成一个_selectControl的实例变量名,_selectControl可以根据自己需求更改,
//如果不声明 @synthesize,则默认下方的操作
@synthesize _ selectControl = selectControl;

2、@dynamic 语义是用户要求自动生成setter getter方法,系统不会自动生成,所以此时调用setter或getter方法会crash,编译不报错(oc的动态绑定机制),而且调用对应的实例变量会报错

  • assign

    用来修改基本数据类型和对象,不涉及内存管理,内存计数不变化,所以如果修饰对象类型的话(一般编译的时候会产生警告:Assigning retained object to unsafe property; object will be released after assignment)会出现野指针或者EXC_BAD_ACCESS错误,因为如果对象被释放后,不会对指针地址进行置nil操作
  • retain

    引用计数+1,对应的setter方法
- (void) setStr:(NSString *)str{
  if (_oldStr !=str){
     [_oldStr release]
     _oldStr = [str retain];
  }
}

NSString *str0 = [str retain];
//str0 和 str 的变量地址相同,指向相同的内容地址,str 的retainCount增加1此对象只能用于Object-c对象类型,而不能用于Core Foundation对象。(基本数据类型 和 CoreFoundation 对象都没有引用计数)当把对象添加到 数组中时,被添加对象的引用计数+1
  • copy

1、指针复制,释放旧对象,然后生成一个计数为1的新对象

- (void) setStr:(NSString *)str{
  if (_oldStr !=str){
     [_oldStr release]
     _oldStr = [str copy];
  }
}

2、一般用来修饰符合NSCopying协议的类型
3、涉及到浅拷贝和深拷贝

1、对不可变对象执行copy操作,是浅拷贝(指针拷贝,内容相同),都指向同一边存储空间,源数据被修改,副本数据也会被修改
2、对不可变字符串执行mutCopy操作,是深拷贝(对象拷贝),两者指向不同的存储空间
3、可变字符串执行copy或mutCopy都是深拷贝
4、可变容器类执行copy或mutcopy或者不可变容器执行mutCopy都是不完全深拷贝,即只是容器对象指向不同的内存空间,内部的元素则指向同一个内存
5、可变数组执行copy(NSMutableArray执行copy后返回的NSArray),在使用过程回出现crash的问题
6、数组完全深拷贝需要执行initWithArray:copyItems: 方法
NSArray *deepCopy = [[NSArray alloc] initWithArray:array copyItems:YES];

4、NSString类型用copy修饰的原因


@interface  obj : NSObject
@property (nonatomic,copy) NSString *str;
@end

//实例化后赋值
obj.str = copyStr;

如果str用strong修饰(strong赋值操作参考下方),而copyStr是可变类型,则上面的赋值操作后,str同copyStr一样指向同一块内存空间,这样如果copyStr发生改变,str也会跟着改变,数据就会出现被篡改的风险;
如果用copy修饰,copy对可变对象执行深拷贝,拷贝出一个新的内存空间,这样就互不影响了

  • weak

1、弱引用,不会持有对象,也就不会有引用计数的变化,一般用来避免循环引用的问题,如果对象被释放,则对应的指针变量会置nil(runtime消息发送机制,对nil发送消息返回空,不会出现异常)

2、weak底层是通过sideTab中的hash表进行管理的,通过对象指针作为key,对应的weak指针数组作为value进行存储,一旦对象被释放,就会通过该对象地址在表中进行查找对应的weak指针数组,然后遍历进行置nil操作

3、与assign的区别

weak修饰的对象销毁的时候,指针会自动设置为nil,而assign不会

4、xib/Storyboard中,系统会自动为控件赋strong,所以拖到代码一般用weak


266345-0c09f2ef2d7ee7ae.png
  • strong

1、强引用,持有对象,引用计数+1,用于延长对象的生命周期

- (void) setStr:(NSString *)str{
  if (_oldStr !=str){
     [str retain ];
     [_oldStr release];
     _oldStr = str;
  }
}

2、一般的指针变量默认是strong类型

  • atomic和nonatomic

1、原子属性,线程安全,读写有加锁(互斥锁)操作,防止多条线程同时访问同一块内存,但是需要消耗大量资源
2、atomic只是对属性的getter/setter方法进行了加锁操作,这种安全仅仅是set/get 的读写安全,并非真正意义上的线程安全,因为线程安全还有读写之外的其他操作(比如:如果当一个线程正在get或set时,又有另一个线程同时在进行release操作,可能会直接crash)
3、非原子属性,不加锁,当多个线程同时访问同一个属性,会出现无法预料的结果,但是性能更好

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342