目录结构:
1.理解内存引用计数
2.以arc简化引用计数
3.在dealloc方法中只释放引用并解除监听
4.编写异常安全代码时留意内存管理问题
5.以弱引用避免保留环
6.以自动释放池块降低内存峰值
7.用僵尸对象调试内存管理问题
8.不要使用retaincount
第六章
1.理解块的概念
块是一个值,有相关类型。
强大之处:在声明它的范围内,所以变量都可以为其捕获。
默认块捕获的变量是不可以修改的,但是声明变量的时候添加__block的修饰符之后,是可以修改的。
函数可以传入内联块。
特别注意:
如果块定义在实例方法中,除了访问类的所以实例变量外,还可以使用self变量。块总能修改实例变量,所以在声明时无需加__block.不过可能在捕获实例变量的同时,把self捕获了。(此处省略若干,需要特别注意)
块分为:全局块,堆块和栈块。
块定义的时候是在栈中的,copy的时候,会拷贝到堆中。拷贝后的块,才能在定义它的那个范围之外使用。
2.为常用的块类型创建typedef
typedef int (^testBlock)(BOOL flag,int value);
3.用handler块降低代码分散程度
类似:
[fetcher doHandle:^(NSData *data){
///
}];
4.用块引用所属对象时不要出现保留环
解决办法:清除环中的某个引用。
网络请求比较容易出现这个问题,最好的办法是把块放在属性中,使用完立即清除。
如:
-(void)requestHandler{
if(_doHandler){
_doHandler(value);
}
self,doHandler = nil;
}
5.多用派发队列,少用同步锁。
同步锁:
方法一:同步块
-(void)doSomeThing
{
@synchronized(self){
//
}
}
方法二:使用NSLock
_lock = [[NSLock alloc] init];
-(void)doSomeThing
{
[_lock lock];
//
[_lock unlock];
}
派发队列:
_syncQueue = dispatch_queue_create("com.xx.syncQueue",NULL);
-(void)doSomeThing
{
dispatch_sync(_syncQueue,^{
//
});
}
6.多用GCD,少用performSelector系列方法
dispatch_async(dispatch_get_main_queue(),^{
//
});
7.掌握GCD及操作队列的使用时机
相比NSOperation,NSOperationQueue类
NSOperation,NSOperationQueue类在以下方面有优势:
1.取消某个操作 2.指定操作间的依赖关系 3.通过键值观察机制监控NSOperation对象的属性。
4.指定操作的优先级 5.重用NSOperation对象。
8.通过dispatch group机制,根据系统资源状况来执行任务
dispatch_group_create
dispatch_group_async
dispatch_group_enter
dispatch_group_leave
dispatch_group_wait
dispatch_group_notify
9.通过dispatch_once 来执行只需要运行一次的线程安全代码
10.不要使用dispatch_get_current_queue