nonatomic, retain,weak,strong用法详解
strong weak
强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。
弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。没办法,还是 “强哥” 有面子。
weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。
__strong 是缺省的关键词。
__weak 声明了一个可以自动 nil 化的弱引用。
__unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
__autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。
之前写一个基于地理位置应用程序的时候无法让应用程序打开定位功能,在.h文件里面,我定义的属性是这样的:
后来,我将上面这句话改为:
就可以了。
接下来,就详细得介绍一下nonatomic, retain,weak,strong
在我们开发iOS程序时,常常会遇到:
property 和synthesize,以前很懒没有仔细去理解,只是看了看别人写的书,觉得挺容易的(在这里我不得不说,现在很多本土出的土书,尤其是早期的2009年,写的是真乱,误人子弟),所以今天有时间,自己试验了一番,希望和大家讨论。property,他可以提供的功能有:提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境 )。property不但可以在interface,在协议[url=]protocol[/url] .和类别[url=]category[/url]中也可以使用.synthesize的理解是:实现property所声明的方法的定义。其实说直白就像是:property声明了一些成员变量的访问方法 ,synthesize则定义了由property声明的方法。他们之前的对应关系是  property 声明方法 ----------》 头文件中申明的方法 synthesize定义方法---------》Cpp文件中定义的方法
不过这里还有有一点细微的差别,后面我会讲到。
先讲property大家都知道:@property(attribute1 , attribute2, ...])是@property的他的官方表达方式,所以看到attribute1, attribute2,你就应该懂的, 他的用法不是很简单。下面就对他的属性列表进行分类介绍:下面对属性列表进行一下简单的介绍,后续会用代码来解释。1.可读性:readonly 、readwrite@property(readwrite,....) valueType value;这个属性是变量的默认属性,就是如果你(readwrite and readonly都没有使用,那么你的变量就是readwrite属性),通过加入readwrite属性你的变量就会有get方法,和set方法。property(readonly,...) valueType value;这个属性变量就是表明变量只有可读方法,也就是说,你只能使用它的get方法。2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序
4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。
5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级.所以 不加nonatomic对与多线程是安全的 。 
其实他们都可以用代码表示:1.nonatomic 和 atomic@property(nonatomic ) NSObject* test1;
@synthesize test1;上面两句代码,表示我们对test1的访问,是非多线程安全的。@property(atomic) NSObject* test1;
@synthesize test1;上面两句代码,表示我们对test1的访问,是多线程安全的。其实也就是在讲该成员变量放到互斥代码中,例如,下面进行加锁。[_internal lock]; // lock using an object-level lock 
id result = [[value retain] autorelease]; 
[_internal unlock]; 
return result;
就如上面所说 ,这两个属性,是出于对多线程条件下 ,对test1的访问安全。如果你的程序的成员变量不存在安全问题,用nonatomic 就好,因为这样不要在访问是进行互斥,效率更高。
2. readonly 、readwrite (注,后续过程我们都会加入nonatomic 属性,因为它是十分普遍的)2.1 readonly@property(nonatomic  ,readonly) NSObject* test1;
@synthesize test1;上面的两句代码,objc编辑器将会为我们翻译为:@property(nonatomic  ,readonly) NSObject* test1; 等同-(NSObject*)test1;
@synthesize test1;等同-(NSObject*)test1{ return test1;}2.2 readwrite 
@property(nonatomic  ,readwrite ) NSObject* test1;
@synthesize test1;上面的两句代码,objc编辑器将会为我们翻译为:@property(nonatomic  ,readwrite ) NSObject* test1; 等同-(NSObject*)test1;
-(void)settest1(NSObject* other);@synthesize test1;等同-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{ test1 = other;}
成员变量的访问权限。所以要抓住他们真正价值。3. assign@property(nonatomic ,assign) NSObject* test1;@synthesize test1;上面两句:objc编辑器将会翻译如下:@property(nonatomic ,assign) NSObject* test1;等同
-(void)settest1(NSObject* other);@synthesize test1;-(void)settest1(NSObject* other);等同
{ test1 = other;}
4. retain@property(nonatomic  ,retain) NSObject* test1;
@synthesize test1;
@property(nonatomic  ,retain) NSObject* test1;等同-(NSObject*)test1;
-(void)settest1(NSObject* other);
-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other) {    if (test1!= other)    {                  [test1release];                   test1= [otherretain];     }}
5. copy@property(nonatomic  ,copy) NSObject* test1;
@synthesize test1;
@property(nonatomic  ,copy) NSObject* test1;
-(NSObject*)test1;
-(void)settest1(NSObject* other);
-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{
[test1release];
test1= [othercopy];
}
}对于Copy属性有一点要主要,被定义有copy属性的对象必须要符合NSCopying协议,并且你还必须实现了-(id)copyWithZone
NSZone*)zone该方法。
代码才是王道:都是一些简单代码用例//为了更具有普遍性,我选择用自定义对象testObj /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .h
@interface testObj : NSObject{
    
}
@end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .m-(id)copyWithZone
NSZone *)zone
{
    testObj* pObj = [[testObj allocWithZone:zone] init];
    return pObj;
}
@end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////testApp是包含多个testObj 对象指针//testApp .h
@interface testApp :
{
    testObj*  test1;
    testObj*  _test2;
}
@property(nonatomic , retain) NSObject* test1;
@property(nonatomic , copy) NSObject* test2;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testApp.m@synthesize test1;@synthesize test2 = _test2;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@synthesize test2 = _test2; //对这里要特别主要一下,这里可以看作是一种别名机制,这点和前面类比的C++头文件和Cpp文件不同。
例如对于setter函数,objc编辑器将会按如下方式翻译如果是@synthesize _test2;setter函数将是这种形式:-(void)set_test2(NSObject*); //注意中间的下划线写成@synthesize test = _test2;setter函数将是这种形式:
-(void)settest2(NSObject*);// _test2 被 test2替换了
可以看出这种别名机制,感觉是规范书写(其实更像是规范Objc的书写,大家可以看看官方文档中,成员变量都是前面带下滑线的(如_test2),所以才搞了这样一个别名规范代码中的书写)
//下面是一个功能函数,-(void )test{test1 = [[testObj alloc]init];// test1  retainCount  =1;
//下面有三种对test2操作方法: _test2 = test1; //这里是将test1的指针赋值给_test2指针,注意,并没有调用test2的setter方法 ,所以test retainCount  = 1、 test2 retainCount  = 0; self.test2 = test1;  //这里调用test2的Copy方法,因此这是test retainCount  = 1、 test2 retainCount  = 1;   test2   = test1; //这段代码系统将会提示出错说test2没有定义。因为这里编译器认为是一条赋值表达式,将test2看作是一个成员变量,而在我们的testApp 中是没有这个成员变量的,这里要区别我们所说的别名,别名机制可以看作是在调用setter或者getter函数才会起作用,而这里只是一个简单的赋值,也就出现未定义的错误。如果没有理解,你就记住要调用setter或者getter函数,就用"self.成员变量"这种形式就行了.
//我们把  test2   = test1这行代码注释掉,保证程序继续执行    [test1 release];  // 释放test1 ,test1 retainCount  = 0;
    
    [test2 release]; // 释放test2 ,test2 retainCount  = 0;
}@end
nonatomic, retain,weak,strong用法详解的更多相关文章
- IOS开发copy,nonatomic, retain,weak,strong用法
		
readwrite 是可读可写特性;需要生成getter方法和setter方法时 readonly 是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变 ass ...
 - jquery之insertBefore(),insertAfter(),prependTo(),appendTo()用法详解
		
导航: 1,insertBefore(),insertAfter(),prependTo(),appendTo()这四个函数用法几乎一样 2, 与之相对的有四个函数:Before(),After(), ...
 - NSString NSMutableString copy mutableCopy retain weak strong整合
		
copy retain assign的差别在于对象属性的set方法 NSString 与 NSMutableString NSString是不可变字符串对象,这句话的意思,结合代码: #import ...
 - C#中string.format用法详解
		
C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...
 - @RequestMapping 用法详解之地址映射
		
@RequestMapping 用法详解之地址映射 引言: 前段时间项目中用到了RESTful模式来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没 ...
 - linux管道命令grep命令参数及用法详解---附使用案例|grep
		
功能说明:查找文件里符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...
 - mysql中event的用法详解
		
一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...
 - CSS中伪类及伪元素用法详解
		
CSS中伪类及伪元素用法详解 伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...
 - c++中vector的用法详解
		
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
 
随机推荐
- Java语言中的基本词汇
			
1.标识符包.类.方法.参数和变量的名称.大小写字母.数字._和$符号的组合,不以数字开始,不能使关键字,不能包括分隔符和换行.(严格区分大小写,最大长度255个字符) 2.字面量 某种类型的值(具 ...
 - [转]Javascript中的自执行函数表达式
			
[转]Javascript中的自执行函数表达式 本文转载自:http://www.ghugo.com/javascript-auto-run-function/ 以下是正文: Posted on 20 ...
 - hydra爆破用法
			
-R 根据上一次进度继续破解 -S 使用SSL协议连接 -s 指定端口 -l 指定用户名 -L 指定用户名字典(文件) -p 指定密码破解 -P 指定密码字典(文件) -e 空密码探测和指定用户密码探 ...
 - openstack虚拟机迁移的操作记录
			
需求说明:计算节点linux-node1.openstack:192.168.1.8 计算节点linux-node2.openstack:192.168.1.17 这两个计算节点在同一个控制节点下( ...
 - Iron man
			
儿子的手办在近期又新增一套钢铁侠,来自于淘宝的玩具推荐,这个推荐也得益于小美和他平日在淘宝商城里的各种玩具浏览,充分体现了现阶段对复仇者联盟成员的喜爱. 一套共六个,有着不同的颜色,但造型基本一致带L ...
 - prepareStatement createStatement
			
preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement. preparedstatemen ...
 - 文件“D:\file.txt”正由另一进程使用,因此该进程无法访问该文件。
			
关于如题的解决方案! 都是有一定编程基础的人,我就不讲其它的了. 1.在实例化一个FileStream后,用完它一定要关闭.先试试这一条: 2.第一条不起作用的话,用本条.在实例化FileStream ...
 - MVC4项目中验证用户登录一个特性就搞定
			
在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性. // 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问. [AttributeUsage(Attribu ...
 - scrapy 登录
			
说明: 本文参考了官网文档,以及stackoverflow的几个问题 注意: 下面这个爬虫不能实际运行!我只是用它来展示登录,以及之后如何处理. 方式一:FormRequest import scra ...
 - python 3 安装 scrapy 并运行成功
			
今天,python 3 安装 scrapy, 并运行成功.特此纪念! 我的环境:windows 10(64位) + python 3.5.2(64位) 其中几个要点说明一下: 1.有几个依赖库需要事先 ...