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 = @"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 = @"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关键字。

strong,weak, unsafe_unretained往往都是用来声明属性的,如果想声明临时变量就得用__strong,  __weak, __unsafe_unretained,  __autoreleasing, 其用法与上面介绍的类似。

还是看看实例吧。

  1. __strong NSString *yourString = @"Your String";
  2. __weak  NSString *myString = yourString;
  3. yourString = nil;
  4. __unsafe_unretained NSString *theirString = myString;
  5. //现在所有的指针都为nil

再看一个:

  1. __strong NSString *yourString = @"Your String";
  2. __weak  NSString *myString = yourString;
  3. __unsafe_unretained NSString *theirString = myString;
  4. yourString = nil;
  5. //现在yourString与myString的指针都为nil,而theirString不为nil,但是是野指针。

__autoreleasing的用法介绍:

在c/c++,objective-c内存管理中有一条是:谁分配谁释放。 __autoreleasing则可以使对像延迟释放。比如你想传一个未初始 化地对像引用到一个方法当中,在此方法中实始化此对像,那么这种情况将是__autoreleasing表演的时候。看个示例:

  1. - (void) generateErrorInVariable:(__autoreleasing NSError **)paramError{
  2. NSArray *objects = [[NSArray alloc] initWithObjects:@"A simple error", nil];
  3. NSArray *keys = [[NSArray alloc] initWithObjects:NSLocalizedDescriptionKey, nil];
  4. NSDictionary *errorDictionary = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
  5. *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];
  6. }
  7. -(void)test
  8. {
  9. NSError *error = nil;
  10. [self generateErrorInVariable:&error];
  11. NSLog(@"Error = %@", error);
  12. }

这样即便在函数内部申请的空间,在函数外部也可以使用,同样也适合谁分配谁释放的原则。

同样下面的代码也是类似原因, 只不过在没有开启ARC的情况下适用:

  1. -(NSString *)stringTest
  2. {
  3. NSString *retStr = [NSString stringWithString:@"test"];
  4. return [[retStr retain] autorelease];
  5. }

开启ARC后,应改为:

  1. -(NSString *)stringTest
  2. {
  3. __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];
  4. return retStr;
  5. }
Setter Semantics

These attributes specify the semantics of a set accessor. They are mutually exclusive.

strong

Specifies that there is a strong (owning) relationship to the destination object.

weak

Specifies that there is a weak (non-owning) relationship to the destination object.

If the destination object is deallocated, the property value is automatically set to nil.

(Weak properties are not supported on OS X v10.6 and iOS 4; use assigninstead.)

copy

Specifies that a copy of the object should be used for assignment.

The previous value is sent a release message.

The copy is made by invoking the copy method. This attribute is valid only for object types, which must implement the NSCopying protocol.

assign

Specifies that the setter uses simple assignment. This attribute is the default.

You use this attribute for scalar types such as NSInteger and CGRect.

retain

Specifies that retain should be invoked on the object upon assignment.

The previous value is sent a release message.

In OS X v10.6 and later, you can use the __attribute__ keyword to specify that a Core Foundation property should be treated like an Objective-C object for memory management:

@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

http://www.33lc.com/article/661.html

iOS property中的strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解的更多相关文章

  1. property中的strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用详解

    iOS5中加入了新知识,就是ARC,其实我并不是很喜欢它,因为习惯了自己管理内存.但是学习还是很有必要的. 在iOS开发过程中,属性的定义往往与retain, assign, copy有关,我想大家都 ...

  2. iOS知识基础篇--@property,@synthesize, nonatomic,atomic,strong,weak,copy,assign,retain详解

    一.@property 这个关键词的唯一作用就是声明getter.setter方法接口. 二.@synthesize 实现setter.getter方法,找不到实例变量则主动创建一个. 三.nonat ...

  3. strong 、weak、copy 、assign 、retain 、unsafe_unretained 与autoreleasing区别和作用

    strong关键字与retain关似,用了它,引用计数自动+1,用实例更能说明一切 @property (nonatomic, strong) NSString *stringA; @property ...

  4. PHP中VC6、VC9、TS、NTS版本的区别与用法详解

    Thread safe(线程安全)是运行在Apache上以模块的PHP上,如果你以CGI的模式运行PHP,请选择非线程安全模式(non-thread safe). 1. VC6与VC9的区别: VC6 ...

  5. 关于@property()的那些属性及ARC简介【nonatomic,atomic,assign,retain,strong,weak,copy。】

    @property()常用的属性有:nonatomic,atomic,assign,retain,strong,weak,copy. 其中atomic和nonatomic用来决定编译器生成的gette ...

  6. IOS atomic与nonatomic,assign,copy与retain的定义和区别

    IOS atomic与nonatomic,assign,copy与retain的定义和区别 atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作.        ...

  7. iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解

    iOS回顾笔记(03) -- 自定义View的封装和xib文件的使用详解 iOS开发中,我们常常将一块View封装起来,以便于统一管理内部的子控件.如iOS回顾笔记(02)中的"书" ...

  8. Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-97讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. shell脚本中常见的一些特殊符号和作用详解

    这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下   在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...

随机推荐

  1. Thinkphp5笔记二:创建模块

    系统:window 7 64位 Thinkphp版本:5.0.5 环境:wampserver集成 我的项目是部署在本地www/thinkphp  目录下.在做之前,先要考虑清楚,你需要几个模块来完成你 ...

  2. 【WP8】仿QQ提示消息

    WP版的QQ提示消息的时候从顶部滑入,3秒后从顶部滑出,本文模仿该效果实现一个MessageToastManager类用于显示提示消息 思路很简单,就是动画而已,支持配置颜色和回掉 // ****** ...

  3. 升级到yosemite后homebrew报错的解决

    报错会如下: /usr/local/bin/brew: /usr/local/Library/brew.rb: /System/Library/Frameworks/Ruby.framework/Ve ...

  4. vim中文手册

    http://vimcdoc.sourceforge.net/doc/help.html

  5. go语言之PLAN9汇编

    http://blog.studygolang.com/2013/05/asm_and_plan9_asm/ https://lrita.github.io/2017/12/12/golang-asm ...

  6. Kafka监控工具KafkaOffsetMonitor配置及使用

    转载:https://www.cnblogs.com/dadonggg/p/8242682.html jar包下载地址 KafkaOffsetMonitor托管在Github上,可以通过Github下 ...

  7. python mysql 封装

    封装 观察前面的文件发现,除了sql语句及参数不同,其它语句都是一样的 创建MysqlHelper.py文件,定义类 #encoding=utf8 import MySQLdb class Mysql ...

  8. Postman模拟Request Payload发送请求

    Postman模拟Request Payload发送请求,如下图所示:

  9. SQLServer------基本操作

    代码: --新增字段 ) --编辑字段名称 --注意: 更改对象名的任一部分都可能会破坏脚本和存储过程 EXEC sp_rename 'FTTxUser.[Modifiersss]','Creator ...

  10. HNOI2015题解

    奇了怪了我上次发的题解怎么不见了? 题意自己戳链接-- Day 1 id=4008">HNOI2015 Arthur 思路:期望DP 直接DP是死也D不出的 转化一下 令f[i][j] ...