1.ARC空声明变量
使用ARC的另一个优势是所有未初始化的变量默认都是“空值化”的。这意味着像下面这样的声明使用ARC编译后指向的是空值(nil):
NSObject *myObject1,*myObjects2;
不过要注意的是,与其他高级编程语言不同,ARC不会自动将标量的值设置为零。
这意味着以下几行代码声明的变量其值并不等于零:
int a;
int b;
2.Objective-C命名约定
如果你在Person对象中写了一个叫做newPersonName的方法,ARC会认为该方法返回一个分配过的对象。使用ARC(或者不适用ARC)编译过的调用代码和方法newPersonName运行时一切正常。但是如果这一方法所在的类没有使用ARC编译而调用方法使用了ARC编译,程序就会奔溃。反过来,如果newPersonName方法是使用ARC编译的而调用代码没有,就会出现内存泄露。
3.覆盖默认行为
虽然从技术上说我们无法覆盖LLVM的行为,但还是可以使用Clang源标注NS_RETURNS_RETAINED和NS_RETURNS_NOT_RETAINED来更改方法。newPersonName方法可以像下面这样标注,以告诉ARC编译器:尽管该方法名称前面是new,返回的却是未保留过的对象指针。
-(NSString *)newPersonName NS_RETURNS_NOT_RETAINED;
4.自由桥接
与Objective-C库不同,我们在Objective-C中使用的标准C语言和Core Fundation类库(CF *方法)不会遵循那些命名约定。这意味着ARC编译器无法百分百地释放不需要的内存。在ARC出现之前,我么可以将CF*对象强制转变成NS*对象,这称为自由桥接(toll-free bridging)。也就是说,我们可以将CFString*通过类型转换变成NSString*类型。而有了ARC,我们便无法再这么做了,至少不指定一个所有权转移修饰符时确实如此。
ARC允许使用一下这些所有权转移修饰符:
__bridge
__bridge_retained
__bridge_transfer
1.__bridge
它告诉ARC不要增加它的引用计数的值,也不要更改所有权。
2.__bridge_retained
若想要转换C指针类型并增加引用计数的值,我们可以使用第二个修饰符。当要从Objective-C方法(它创建一个Core Fundation对象并在之后使用CFRelease方法将其释放)返回一个保留过的指针时,我们可以使用这个修饰符。如果Objective-C方法属于NSRETURNS_RETAINDED系列,就要返回保留过的指针。
3.__bridge_transfer
如果要将Core Fundation指针类型转换成Objective-C指针并为引用计数加1,可以使用最后一个修饰符。若Core Fundation方法创建一个对象,并且想要靠ARC来管理对象的内存,我们便可以使用这个修饰符。
5.忽略performSelector警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[uiViewController performSelector:finishMethod withObject:request];
#pragma clang diagnostic pop
6.block引起的循环保留
使用__block避免循环保留(无ARC)
__block id safeSelf = self;
self.myBlock = ^(NSString* returnedString){
safeSelf.labelControl.text = returnedString;
};
ARC会改变__block的语义,因此不应该使用它。在ARC中,__block引用会被保留而不是被复制,这意味着在ARC环境中前面的代码仍然会引发循环保留。正确地方法是使用__weak或(__unsafe_unretained)引用,如:
使用__weak避免循环保留(有ARC)
__weak typeof(self) safeSelf = self;//IOS 5+
//__unsafe_unretained typeof(self) safeSelf = self;//IOS 4+
self.myBlock = ^(NSString* returnedString){
safeSelf.labelControl.text = returnedString;
};
- 推荐文章
- python网络编程【一】
- python时间格式化
- css九宫格自适应的实现
- 改变你代码习惯的ES6
- 深入理解Javascript闭包
- 前端里的库和框架?
- 编写高质量的代码基础:结构和样式,行为的分离
- Sass也许你想和CSS玩耍起来(上篇)
- 也许你需要点实用的Web前端笔试题
- Sass也许你想和CSS玩耍起来(下篇)
- CSS性能分析,如何优化CSS提高性能
- 深入理解Javascript作用域和赋值操作
- Web前端面试笔试题总结
- 走进SVG
- JavaScript小细节点罗列(1)
- 实用的Javascript获取网页屏幕可见区域高度
- SpringBoot(七):SpringBoot中如何使用过滤器(Filter)?
- SpringBoot启动报错 Disconnected from the target VM, address: '127.0.0.1:2227', transport: 'socket'
- SpringBoot(五):SpringBoot使用拦截器
- SpringBoot(一):使用IDEA快速搭建一个SpringBoot项目(详细)
- SpringBoot(八):SpringBoot中配置字符编码 Springboot中文乱码处理
- SpringBoot(二): SpringBoot属性配置文件 SpringBoot多环境配置文件 SpringBoot自定义配置文件
- 使用Maven新建SpringBoot工程
- SpringBoot(四): SpringBoot web开发 SpringBoot使用jsp
- SpringBoot(三):SpringBoot热部署插件
- SpringBoot(六):SpringBoot中如何使用Servlet?
- ARQ自动重传请求与UDP提供可靠交付
- 多线程程序中操作的原子性转帖
- 多目录的Makefile
- VC++小小绘图程序