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

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

一、简介

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

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

二、原理

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

三、strong指针

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

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

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

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

2.如果执行了如下代码

NSString *name = self.nameField.text;

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

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

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

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

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

  name = @"Jake";

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

四、weak指针

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

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.subViews)拥有一个UITableView, UITableView的dataSource和delegate都是weak指针,指向你的ViewController

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

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

  __weak NSString *str = [[NSString alloc] initWithFormat:@"1234"];

  NSLog(@"%@", str); // 打印出来是"(null)"

str是个weak指针,所以NSString对象没有拥有者,在创建之后就会被立即释放。Xcode还会给出警告("Warning: Assigning retained object to weak variable; object will be released after assignment")

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

  NSString *name = self.nameField.text;

  __strong NSString *name = self.nameField.text;

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

  @property (nonatomic, strong) NSString *name;    

  @property (nonatomic, weak) id delegate;

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

  id obj = [array objectAtIndex:0];  //从数组array中取出索引为0的对象,用obj变量来接收。

  [array removeObjectAtIndex:0];   //让array将索引为0的对象移除。(非ARC,加入array的对象,所有权交由数组来管理)

  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方法(也不能在dealloc方法里面去调[super dealloc]方法),不能调用retain,release,autorelease,retainCount方法,包括@selector(retain)的方式也不行;

2.可以用dealloc方法来管理一些资源,但不能用来释放实例变量如[self.name release],也不能在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。

转载于:https://www.cnblogs.com/stevenwuzheng/p/5358920.html

Objective-C中,ARC下的 strong和weak指针原理解释相关推荐

  1. ARC指南 strong和weak指针

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

  2. iOS arc weak指针原理

    iOS arc weak指针原理 ARC 都帮我们做了什么? weak是什么? weak是怎么实现的? 1. weak原理简介 2. weak简单测试 3. weak原理分析 3.1 weak指针帮我 ...

  3. iOS 中strong,weak,copy,assign区别

    1:ARC环境下,strong代替retain.weak代替assign 2:weak的作用:在ARC环境下,,所有指向这个对象的weak指针都将被置为nil.这个T特性很有用,相信很多开发者都被指针 ...

  4. [转]iOS5 ARC学习笔记:strong、weak等详解

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

  5. [iOS]ARC下循环引用的问题

    转载自:http://blog.cnbang.net/tech/2085/ [iOS]ARC下循环引用的问题 2013-8-30 最初 最近在开发应用时碰到使用ASIHttpRequest后在某些机器 ...

  6. IOS学习 ARC下__bridge

    总结于 IOS Tuturial 中 ARC两章,详细在dropbox pdf 文档. Toll-Free Bridging 当你在 Objective-C 和 Core Foundation 对象之 ...

  7. iOS 5中的strong和weak关键字

    from:http://blog.csdn.net/yhawaii/article/details/7291134 iOS 5 中对属性的设置新增了strong 和weak关键字来修饰属性(iOS 5 ...

  8. [ios] iOS中arc的设置与使用

    旧工程配置arc方案: 1,直接在targets->build phases中修改compiler Flags,是否支持arc.添加:-fobjc-arc,就可以让旧项目支持arc.如果想让原来 ...

  9. ios 内存管理的理解(四)ARC下循环引用问题

    案例 一个人拥有一只狗,一只狗拥有一个主人. @interface Person :NSObject@property(nonatomic,strong) Dog* dog; @end @interf ...

最新文章

  1. 关于程序猿的学习方法的一些总结
  2. 解决“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”(转贴)...
  3. phpmyadmin教程
  4. Xamarin.Forms单元控件Cell
  5. tensorflow常见问题
  6. 基于组件的案例:购物车
  7. DevOps简单介绍
  8. eval在python中是什么意思_如何在Python中使用eval ?
  9. java中的values函数_巧用valueat函数(快逸免费版)
  10. OceanBase数据库实践入门——性能测试建议
  11. Linux中ftp密码输错无响应,psftp登陆输入正确用户名和密码后无响应解决办法
  12. Selenium API-WebElement 属性
  13. eclipse修改java热部署免重启tomcat在Host标签下增加Context直接将docBase指定为项目的WebContent路径
  14. 20200222:串联所有单词的子串(leetcode30)
  15. 【渝粤教育】电大中专学前儿童社会教育 (11)作业 题库
  16. ios开发笔记之 emoji表情字符编码集合
  17. access mysql 操作方法_设置和取消Access数据库密码-图解教程
  18. threejs学习第一天--3D地月环绕实战案例
  19. PS如何修改gif动图 播放速度 - 本地方法篇
  20. 微信公众平台订阅号和服务号的区别详解

热门文章

  1. mysql7.5安装教程_CentOS7.5下yum安装MySQL8图文教程
  2. html 页面重复度高,哪些情况容易造成重复页面
  3. 韩顺平php教程笔记,PHP笔记,韩顺平php笔记_PHP教程
  4. java bean id_在 JSP中使用JavaBean的标签是 ,其中 id的用途是 __________________学小易找答案...
  5. 1062 最简分数(PAT乙级 C++)
  6. 工业级以太网交换机具有哪些优越特性
  7. 【渝粤教育】电大中专幼儿园课程论 (8)作业 题库
  8. 【渝粤教育】电大中专消费者行为学30分钟交卷作业 题库
  9. [渝粤教育] 西南科技大学 英语语法1 在线考试复习资料
  10. 【渝粤题库】陕西师范大学201381 国际经济法作业