ARC指南1 - strong和weak指针

时间:2022-09-25 22:15:43
 

一、简介

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

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

二、原理

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

三、strong指针

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

  1. @property (nonatomic, assign) IBOutlet UITextField *nameField;

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

ARC指南1 - strong和weak指针

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

ARC指南1 - strong和weak指针

2.如果执行了如下代码

  1. NSString *name = self.nameField.text;

一个对象可以有多个拥有者,在上面代码中,name变量同样也是这个NSString对象的拥有者,也就是有两个指针指向同一个对象

ARC指南1 - strong和weak指针

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

ARC指南1 - strong和weak指针

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

ARC指南1 - strong和weak指针

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

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

  1. name = @"Jake";

ARC指南1 - strong和weak指针

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

四、weak指针

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

1.执行下面的代码

  1. __weak NSString *name = self.nameField.text;

ARC指南1 - strong和weak指针

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

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

ARC指南1 - strong和weak指针

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

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

ARC指南1 - strong和weak指针

五、strong和weak指针的使用注意

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

  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修饰,以下两行代码是等价的:

  1. NSString *name = self.nameField.text;
  2. __strong NSString *name = self.nameField.text;

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

  1. @property (nonatomic, strong) NSString *name;
  2. @property (nonatomic, weak) id delegate;

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

  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

ARC指南1 - strong和weak指针的更多相关文章

  1. Objective-C中,ARC下的 strong和weak指针原理解释

    Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是& ...

  2. ARC - strong和weak指针

    ARC指南1 - strong和weak指针   提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量&qu ...

  3. ARC指南 strong和weak指针

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

  4. (转)ARC指南 - strong、weak指针

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

  5. swift ARC中的strong、weak、unowned

    Swift 用自动引用计数ARC(Automatic Reference Counting)方式来跟踪和管理app的内存使用.这使得内存管理成为swift内部的机制,不需要认为考虑.ARC会自动释放那 ...

  6. ARC机制中的Strong和weak

    什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化.ARC是新的LLVM 3.0编译 ...

  7. Objective-C中copy 、retain以及ARC中新加入的strong、weak关键字的含义

    copy: 创建一个引用计数为1的对象,然后释放旧的对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的引用计数为 1 Copy其实是建立了一个相同的对象,而retain不是: ...

  8. iOS5 ARC,IBOutlets 应该定义strong还是weak

    转自:http://blog.csdn.net/yiyaaixuexi/article/details/7864974 写这篇文章的缘由,是因为我泡在*上翻帖子,看到一个名为S ...

  9. strong,weak, retain, assign的区别

    strong,weak, retain, assign的区别 strong与weak是由ARC新引入的对象变量属性 xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain ...

随机推荐

  1. 获取文件的缩略图Thumbnail和通过 AQS - Advanced Query Syntax 搜索本地文件

    演示如何获取文件的缩略图 FileSystem/ThumbnailAccess.xaml <Page x:Class="XamlDemo.FileSystem.ThumbnailAcc ...

  2. Navi&period;Soft30&period;产品&period;格式化&period;操作手册

    1系统简介 1.1功能简述 在软件开发过程中,我们对字符串操作最多. 尤其是Web开发时,数据交换一般采用JSON或XML.本产品作用是格式化各种常用字符串,目前包括:Json,Xml,Html,Sq ...

  3. java事务管理

    一.什么是Java事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性(isol ...

  4. jquery upload

    http://blueimp.github.io/jQuery-File-Upload/ https://github.com/blueimp/jQuery-File-Upload/wiki Back ...

  5. java 面对对象(抽象 继承 接口 多态)

    什么是继承? 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可. 多个类可以称为子类,单独这个类称为父类.超类或者基类. 子类可以直接 ...

  6. Angular利用&commat;ViewChild在父组件执行子组件的方法

    代码如下: @Component({ selector: 'my-app', template: ` <step-bar #stepBar></step-bar> ` }) e ...

  7. 【DB2】清理日志文件db2diag&period;log

    在数据库运行过程中,会产生很多的日志,进而使日志文件db2diag.log变大 当占用磁盘空间太大的时候,应该怎么处理呢? 方法一: db2inst1@Linux:/db2home/db2inst1/ ...

  8. NTC电阻抑制冷机启动浪涌电流

    开关电源高压直流回路中常用串联负温度系数热敏限流电阻器(NTC)的方法抑制开机浪涌电流,然而这种简单的方法具有很多缺点:如NTC电阻器的限流效果受环境温度影响较大.限流效果在短暂的输入主电网中断(约几 ...

  9. Asp&period;Net微信支付接口之jsApiPay教程

      1.微信支付JsApiPay只能在微信浏览器中使用 2.必须先申请微信支付功能 3.设置域名 4.设置支付授权目录 一定要精确到最后一级目录 5.获取APPID和AppSecret AppSecr ...

  10. 【点分治】【FFT】CDOJ1562 Amaz1ng Prime

    统计路径的时候,显然用母函数的思想,可以用FFT来方便统计. 注意!要减去路径两个端点相同的情况!然后再除以二!这样防止重复. 还有就是说啊,点分治的正确姿势还是应该用所有子树的答案减去各个子树分别的 ...