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)拥有一个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()打印该对象就会导致应用崩溃
- id obj = [array objectAtIndex:0];
- [array removeObjectAtIndex:0];
- 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使用注意总结
NSString NSArray 是 copy
假如有一个NSMutableString,现在用他给一个retain修饰 NSString赋值,那么只是将NSString指向了NSMutableString所指向的位置,并对NSMUtbaleString计数器加一,
此时,如果对NSMutableString进行修改,也会导致NSString的值修改,原则上这是不允许的.
如果是copy修饰的NSString对象,在用NSMutableString给他赋值时,会进行深拷贝,及把内容也给拷贝了一份,两者指向不同的位置,即使改变了NSMutableString的值,NSString的值也不会改变.所以用copy是为了安全,防止NSMutableString赋值给NSString时,前者修改引起后者值变化而用的.
ARC指南 strong和weak指针的更多相关文章
- (转)ARC指南 - strong、weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因为编 ...
- ARC指南1 - strong和weak指针
一.简介 ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain.release.autorelease语句.你不再需要担心内存管理,因 ...
- ARC - strong和weak指针
ARC指南1 - strong和weak指针 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是"本地变量&qu ...
- Objective-C中,ARC下的 strong和weak指针原理解释
Objective-C中,ARC下的 strong和weak指针原理解释 提示:本文中所说的"实例变量"即是"成员变量","局部变量"即是& ...
- ARC机制中的Strong和weak
什么是ARC Automatic Reference Counting,自动引用计数,即ARC,可以说是WWDC2011和iOS5所引入的最大的变革和最激动人心的变化.ARC是新的LLVM 3.0编译 ...
- Objective-C中copy 、retain以及ARC中新加入的strong、weak关键字的含义
copy: 创建一个引用计数为1的对象,然后释放旧的对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的引用计数为 1 Copy其实是建立了一个相同的对象,而retain不是: ...
- iOS5 ARC,IBOutlets 应该定义strong还是weak
转自:http://blog.csdn.net/yiyaaixuexi/article/details/7864974 写这篇文章的缘由,是因为我泡在stackoverflow上翻帖子,看到一个名为S ...
- strong,weak, retain, assign的区别
strong,weak, retain, assign的区别 strong与weak是由ARC新引入的对象变量属性 xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain ...
- IOS开发 strong,weak,retain,assign,copy nomatic 等的区别与作用
strong,weak,retain,assign,copy nomatic 等的区别 copy与retain:1.copy其实是建立了一个相同的对象,而retain不是:2.copy是内容拷贝,re ...
随机推荐
- Struck 跟踪算法(二)
以下開始读详细源代码 config.h文件 /* * Struck: Structured Output Tracking with Kernels * * Code to accompany the ...
- 用OpenSSL把二进制的Cer证书转换程Base64格式的PEM格式的证书
openssl x509 -inform der -in /d/ty.cer -pubkey -noout > /d/certificate_publickey.pem
- XML文件生成C++代码(基于pugixml)
简述 在一个项目中需要用到XML的解析和生成,知乎上有人推荐rapidxml和pugixml等库.RapidXML一看库还比较大,就先研究一下pugixml了. 因为对解析XML的需求不大(都是一些很 ...
- mysql触发器 学习
1. 说明: 触发器的定义就是说某个条件成立的时候,你触发器里面所定义的语句就会被自动的执行.因此触发器不需要人为的去调用,也不能调用.然后,触发器的触发条件其实在你定义的时候就已经设定好 ...
- vs code 问题:preLaunchTask“build”已终止,退出代码为 1。解决办法
菜单:任务-配置任务 改为如下: { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation ab ...
- Java微信分享接口开发
发布时间:2018-11-07 技术:springboot+maven 概述 微信JS-SDK实现自定义分享功能,分享给朋友,分享到朋友圈 详细 代码下载:http://www.demodas ...
- Ubuntu远程桌面,如何退出全屏
首先安装Linux 下远程桌面客户端软件-rdesktop 打开终端 执行sudo apt-get install rdesktop 远程连接XP 系统(前提是windows xp 必须打开并且允许远 ...
- java struts2入门学习--OGNL语言基本用法
一.知识点学习 1.struts2中包含以下6种对象,requestMap,sessionMap,applicationMap,paramtersMap,attr,valueStack; 1)requ ...
- 蛋疼的经历--wireshark不能启动的问题
事情是这样子的,最近新入职,安装了wireshark,,,在急需要其观察数据包结构,,,,写代码时,,,,卡了,,,我的天!!! 刚开始是提示说,找不到动态链接库api-ms-win-crt-runt ...
- 【转】expect语言学习笔记
上周mentor要求我写一个unix shell 脚本, 以便半夜让服务器自动编译image. 其实我觉得每天我走的时候让服务器编译不也挺好的么... 我懒,假装没听见好不容易赖过去了. ...