zoukankan      html  css  js  c++  java
  • 对于atomic nonatomic assign retain copy strong weak的简单理解

    atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作

    1)atomic

            设置成员变量的@property属性时,atomic是默认值,提供多线程安全

            在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic后setter函数会变成下面这样:

            {lock}

                    if (property != newValue) { 

                            [property release]; 

                            property = [newValue retain]; 

                    }

            {unlock}

     

    2)nonatomic

            若是禁止多线程,实现变量保护,提高性能,可设置成员变量的@property属性为nonatomic

            atomic是Objective-C使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

            指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定 nonatomic ,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。

     

    3)assign

            此标记说明设置器直接进行赋值,assign默认值针对基础数据类型(NSInteger, CGFloat)和C数据类型(int, float, double, char)等。

            在使用垃圾收集的应用程序中,如果你要一个属性使用assign,且这个类符合NSCopying协议,你就要明确指出这个标记,而不是简单地使用默认值,否则的话,你将得到一个编译警告。这再次向编译器说明你确实需要赋值,即使它是可拷贝的。

     

    4)retain

           指定retain会在赋值时唤醒传入值的retain消息,对其他的NSObject和其子类对参数先进行release旧值,再retain新值

           此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。

            注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。

     

    5)copy

            对NSString 它指出在赋值时使用传入值的一份拷贝。拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。更深入的讨论,请参考“复制”部分。

     

    6)copy与retain

    copy其实是建立了一个相同的对象,而retain不是

    (1). 比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。

    (2). 新的对象retain为1 ,旧有对象没有变化,retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然也相同,但这个对象的retain值+1了。

    总结:retain 是指针拷贝,copy 是内容拷贝。

     

    7)assign与retain

    (1). 如果接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给了b(使用assign操作)。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。

    (2). 了解到(1)中assign的问题后,那么如何解决呢?最简单的一个方法就是使用引用计数(reference counting),即使用retain。还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存,b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。

    总结:上面两点其实就是assign和retain的区别。assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign,因为不需要考虑引用计数的问题。而retain就如2中所述,使用了引用计数retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

    =============================================================

    iOS中的strong、weak等详解

    转载自:http://blog.csdn.net/yhawaii/article/details/7291134

    iOS 5 中对属性的设置新增了strong 和weak关键字来修饰属性(iOS 5 之前不支持ARC)

    strong 用来修饰强引用的属性;

    @property (strong) SomeClass * aObject; 
    对应原来的 
    @property (retain) SomeClass * aObject; 和 @property (copy) SomeClass * aObject; 

    weak 用来修饰弱引用的属性;
    @property (weak) SomeClass * aObject; 
    对应原来的 
    @property (assign) SomeClass * aObject; 

    __weak, __strong 用来修饰变量,此外还有 __unsafe_unretained, __autoreleasing 都是用来修饰变量的。
    __strong 是缺省的关键词
    __weak 声明了一个可以自动 nil 化的弱引用。
    __unsafe_unretained 声明一个弱应用,但是不会自动 nil 化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
    __autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。

    引申阅读:
    Beginning ARC in iOS 5 Tutorial Part 1:http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
    ARC简介:http://blog.csdn.net/nicktang/article/details/6887569

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    转载自:http://mobile.51cto.com/iphone-386301.htm

    iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存。但是学习还是很有必要的。

    在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都很熟悉了,在此我也不介绍,网上有很多相关文章。

    现在我们看看iOS5中新的关键字strong, weak, unsafe_unretained. 可以与以前的关键字对应学习strong与retain类似,weak与unsafe_unretained功能差不多(有点区别,等下会介绍,这两个新 关键字与assign类似)。在iOS5中用这些新的关键字,就可以不用手动管理内存了,从java等其它语言转过来的程序员非常受用。

    strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切

    1. @property (nonatomic, strong) NSString *string1;   
    2. @property (nonatomic, strong) NSString *string2;

    有这样两个属性

    1. @synthesize string1;   
    2. @synthesize string2; 

    猜一下下面代码将输出什么结果?

    1. self.string1 = @"String 1";   
    2. [self.string2 = self.string1;   
    3. [self.string1 = nil;  
    4. [NSLog(@"String 2 = %@", self.string2); 

    结果是:String 2 = String 1

    由于string2是strong定义的属性,所以引用计数+1,使得它们所指向的值都是@"String 1", 如果你对retain熟悉的话,这理解并不难。

    接着我们来看weak关键字:

    如果这样声明两个属性:

    1. @property (nonatomic, strong) NSString *string1;   
    2. @property (nonatomic, weak) NSString *string2; 

    并定义

    1. @synthesize string1;   
    2. @synthesize string2; 

    再来猜一下,下面输出是什么?

    1. self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];   
    2. self.string2 = self.string1;   
    3. self.string1 = nil;  
    4. NSLog(@"String 2 = %@", self.string2); 

    结果是:String 2 = null

    分析一下,由于 self.string1与self.string2指向同一地址,且string2没有retain内存地址,而self.string1=nil释放 了内存,所以string1为nil。声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。在 c/c++开发过程中,为何大牛都说指针的空间释放了后,都要将指针赋为NULL. 在这儿用weak关键字帮我们做了这一步。

    接着我们来看unsafe_unretained关键字:

    从名字可以看出,unretained且unsafe,由于是unretained所以与weak有点类似,但是它是unsafe的,什么是unsafe的呢,下面看实例。

    如果这样声明两个属性:

    并定义

    1. @property (nonatomic, strong) NSString *string1;   
    2. @property (nonatomic, unsafe_unretained) NSString *string2; 

    再来猜一下,下面的代码会有什么结果?

    1. self.string1 = [[NSString alloc] initWithUTF8String:"string 1"];   
    2. self.string2 = self.string1;   
    3. self.string1 = nil;  
    4. NSLog(@"String 2 = %@", self.string2); 

    请注意,在此我并没有叫你猜会有什么输出,因为根本不会有输出,你的程序会crash掉。 原因是什么,其实 就是野指针造成的,所以野指针是可怕的。为何会造成野指针呢?同于用unsafe_unretained声明的指针,由于 self.string1=nil已将内存释放掉了,但是string2并不知道已被释放了,所以是野指针。然后访问野指针的内存就造成crash.  所以尽量少用unsafe_unretained关键字

  • 相关阅读:
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Python位运算符
  • 原文地址:https://www.cnblogs.com/fuunnyy/p/4663103.html
Copyright © 2011-2022 走看看