iOS,@property,@synthesize, nonatomic,atomic,strong,weak,copy,assign,retain解析

在申明属性时,一直在使用这些关键词,但对这些关键词的理解并不是很到位,今天有时间查了一些资料,整理了一下,主要是让自己理解的更到位。

一、@property

这个关键词的唯一作用就是声明getter、setter方法接口。

二、@synthesize

实现setter、getter方法,找不到实例变量则主动创建一个。

三、nonatomic与atomic

       atomic原子操作,提供多线程安全,setter方法会发生变化;基本来讲是防止在写未完成的时候被另外一个线程读取,造成数据错误,但是这种操作的弊端就是非常消耗内存资源,苹果手机的内存资源相当宝贵,所以没有使用多线程间的通讯编程,用nonatomic是一个不错的选择。
       指出访问器不是原子操作,而默认地,访问器是原子操作。也就是说 ,在多线程环境下,解析的访问器提过一个队属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行方未能。如果没有指定nonatomic,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了nonatomic,那么访问器只是简单的返回这个值。

四、assign、retain、copy,这是三个关键词得好好说一下。

如:NSString * house = [[NSString alloc] initWithFormat:@"The house is mine"];
首先在上分配一段内存来存储@"The house is mine", 假设内存地址为:0X000 内容则为:@"The house is mine"

然后在上分配一段内存存储house,假设地址为0XFFFF,内容就是0X0000

1、assign:NSString * myHouse = [house assign];

此时housemyHouse完全相同,地址都为0XFFFF内容为0X0000,也就是说myHouse只是house的一个别名,对任何一个操作就等于对另一个操作,因此retainCount不需要增加

2、retain:NSString * myHouse = [house retain];

此时myHouse地址不再是0XFFFF可能是0XEEEE,但内容为0X0000,所以说housemyHouse都可以管理"The house is mine"所在的内存,因此retainCount需要增加1

3、copy:NSString * myHouse = [house copy];

此时会在堆上 重新开辟一段内存存放@"The house is mine",假设 内存地址为:0X1111,内容则为:@"The house is mine"

同时会在栈上为myHouse分配内存,假设地址为:0XBBBB,内容为:0X1111,也就是说myHouse是一个新的对象,与house没有任何关系,很明显,retainCount增加1,

五、strong与weak(下面内容摘自:http://blog.csdn.net/q199109106q/article/details/8565017

参考文献:  iOS ARC 完全指南

提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量"


5-1、简介

ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切

注意:ARC 是编译器特性,而不是 iOS 运行时特性(除了weak指针系统),它也不是类似于其它语言中的垃圾收集器。因此 ARC 和手动内存管理性能是一样的,有时还能更加快速,因为编译器还可以执行某些优化


5-2、原理

ARC 的规则非常简单只要还有一个变量指向对象,对象就会保持在内存中。当指针指向新值,或者指针不再存在时,相关联的对象就会自动释放。这条规则对于实例变量、synthesize属性、局部变量都是适用的


5-3、strong指针

控制器中有个文本输入框框属性

[java]  view plain  copy
  1. @property (nonatomic, assign) IBOutlet UITextField *nameField;  

1.如果用户在文本框中输入mj这个字符串

那么就可以说,nameField的text属性是NSString对象的指针,也就是拥有者,该对象保存了文本输入框的内容


2.如果执行了如下代码

[java]  view plain  copy
  1. NSString *name = self.nameField.text;  
一个对象可以有多个拥有者,在上面代码中,name变量同样也是这个NSString对象的拥有者,也就是有两个指针指向同一个对象

3.随后用户改变了输入框的内容,比如

此时nameFeild的text属性就指向了新的NSString对象。但原来的NSString对象仍然还有一个所有者(name变量),因此会继续保留在内存中


4.当name变量获得新值,或者不再存在时(如局部变量方法返回时、实例变量对象释放时),原先的NSString对象就不再拥有任何所有者,retain计数降为0,这时对象会被释放

如,给name变量赋予一个新值

[java]  view plain  copy
  1. name = @"Jake";  


我们称name和nameField.text指针为"Strong指针",因为它们能够保持对象的生命。默认所有实例变量和局部变量都是Strong指针


5-4、weak指针

weak型的指针变量仍然可以指向一个对象,但不属于对象的拥有者

1.执行下面的代码

[java]  view plain  copy
  1. __weak NSString *name = self.nameField.text;  

name变量和nameField.text属性都指向同一个NSString对象,但name不是拥有者


2.如果文本框的内容发生变化,则原先的NSString对象就没有拥有者,会被释放,此时name变量会自动变成nil,称为空指针

weak型的指针变量自动变为nil是非常方便的,这样阻止了weak指针继续指向已释放对象,避免了野指针的产生,不然会导致非常难于寻找的Bug,空指针消除了类似的问题


3.weak指针主要用于“父-子”关系,父亲拥有一个儿子的strong指针,因此父亲是儿子的所有者;但为了阻止所有权循环,儿子需要使用weak指针指向父亲。典型例子是delegate模式,你的ViewController通过strong指针(self.view)拥有一个UITableView, UITableView的dataSource和delegate都是weak指针,指向你的ViewController


5-5、strong和weak指针的使用注意

1.下面代码是有问题的:

[java]  view plain  copy
  1. __weak NSString *str = [[NSString alloc] initWithFormat:@"1234"];  
  2. NSLog(@"%@", str); // 打印出来是"(null)"  
str是个weak指针,所以NSString对象没有拥有者,在创建之后就会被立即释放。Xcode还会给出警告("Warning: Assigning retained object to weak variable; object will be released after assignment")


2.一般的指针变量默认就是strong类型的,因此一般我们对于strong变量不加__strong修饰,以下两行代码是等价的:

[java]  view plain  copy
  1. NSString *name = self.nameField.text;  
  2. __strong NSString *name = self.nameField.text;  


3.属性可以是strong或weak,写法如下

[java]  view plain  copy
  1. @property (nonatomic, strong) NSString *name;  
  2. @property (nonatomic, weak) id delegate;  

4. 以下代码在ARC之前是可能会行不通的,因为在手动内存管理中,从NSArray中移除一个对象时,这个对象会发送一条release消息,可能会被立即释放。随后NSLog()打印该对象就会导致应用崩溃

[java]  view plain  copy
  1. id obj = [array objectAtIndex:0];  
  2. [array removeObjectAtIndex:0];  
  3. NSLog(@"%@", obj);  
在ARC中这段代码是完全合法的,因为obj变量是一个strong指针,它成为了对象的拥有者,从NSArray中移除该对象也不会导致对象被释放


六、ARC小结

1.有了ARC,我们的代码可以清晰很多,你不再需要考虑什么时候retain或release对象。唯一需要考虑的是对象之间的关联,也就是哪个对象拥有哪个对象?

2.ARC也有一些限制:

1> 首先ARC只能工作于Objective-C对象,如果应用使用了Core Foundation或malloc()/free(),此时还是需要你来手动管理内存

2> 此外ARC还有其它一些更为严格的语言规则,以确保ARC能够正常地工作

3.虽然ARC管理了retain和release,但并不表示你完全不需要关心内存管理的问题。因为strong指针会保持对象的生命,某些情况下你仍然需要手动设置这些指针为nil,否则可能导致应用内存不足。无论何时你创建一个新对象时,都需要考虑谁拥有该对象,以及这个对象需要存活多久

4.ARC还能很好地结合C++使用,这对游戏开发是非常有帮助的。对于iOS 4,ARC有一点点限制(不支持weak指针),但也没太大关系


七、ARC使用注意总结

1.不能直接调用dealloc方法,不能调用retain,release,autorelease,retainCount方法,包括@selector(retain)的方式也不行
2.可以用dealloc方法来管理一些资源,但不能用来释放实例变量,也不能在dealloc方法里面去掉[super dealloc]方法,在ARC下父类的dealloc同样由编译器来自动完成
3.Core Foundation类型的对象仍然可以用CFRetain,CFRelease这些方法
4.不能再使用NSAllocateObject和NSDeallocateObject对象
5.不能在C结构体中使用对象指针,如果有类似功能可以创建一个Objective-C类来管理这些对象
6.在id和void*之间没有简便的转换方法,同样在Objective-C和Core Foundation类型之间的转换都需要使用编译器制定的转换函数
7.不能再使用NSAutoreleasePool对象,ARC提供了@autoreleasepool块来代替它,这样更有效率
8.不能使用内存存储区(不能再使用NSZone)
9.不能以new为开头给一个属性命名
10.声明IBOutlet时一般应当使用weak,除了对StoryBoard这样nib中间的顶层对象要用strong
11.weak相当于老版本的assign,strong相当于retain



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值