1.总体概述
1.1 当使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1。当不再使用该对象时,你需要向该对象发送一条release或autorelese消息。
1.2 当任何通过其它方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,不需要执行任何操作来确保该对象被清理。如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它。
1.3 如果保留了某个对象,需要释放或者自动释放该对象,必须保持retain方法和release方法的使用次数相等。
2.Object里block内存管理
(1)block copy操作
1.当block在栈上时,并不会对_block变量产生强作用。
2.当block被copy到堆时,会调用block内部的copy函数。
2.1 copy函数会调用_Block_object_assign函数。
2.2 _Block_object_assign函数会对__block变量形成强引用(retain)。
(2) block dispose操作
1 当block从堆中移除时,会调用block内部的dispose函数。
1.1 dispose函数内部会调用_Block_object_dispose函数。
1.2 _Block_object_dispose函数会自动释放引用的_block变量(release)。
3.Object里block循环引用
在使用block回调过程中很容易产生一个循环引用的场景,下面是一个示例的循环引用场景。也会有相应的解决办法。
(void)excuteBlock
{
self.age = @"20";
if (customerBlock) {
customerBlock();
}
if (customerBlockPara) {
customerBlockPara(self);
}
}
- (void)demoPara:(CustomerBlockWithPara)paraBlock
{
customerBlockPara = paraBlock;
}
- (void)dealloc
{
NSLog(@"dealloc");
}
@end
通过去制造一个循环引用的例子,使用了SonObject中的age属性
SonObject *son = [[SonObject alloc] init];
[son demo:^{
if ([son.age isEqualToString:@"20"]) {
NSLog(@"====%@",@"right");
}
}];
[son excuteBlock];
这个例子中,on引用了customerBlock(它是SonObject中的全局成员变量),之后在customerBlock中又引用了SonObject的age属性,所以造成了循环引用。最后SonObject中的dealloc函数并没有执行,即son对象并没有被释放掉。
解决以上的循环引用造成的问题,可以让son这个对象得以释放掉,这样就不会存在去循环引用了。
//方法,创建一个指向son的弱引用对象
SonObject *son = [[SonObject alloc] init];
__weak typeof(son) weakSelf = son;
//NSLog(@"test address -- %@",_sonObject);
[son demo:^{
if ([weakSelf.age isEqualToString:@"20"]) {
NSLog(@"====%@",@"right");
}
}];
[son excuteBlock];
3.Object里block的一些优缺点
3.1 优点
(1) 可以把回调函数直接写在需要触发的地方,这样会使代码更具有连续性。
(2) 在代码块内部可以去访问函数内部的变量。
3.1 缺点
(1)如果你的block使用不慎,将会引起内存泄露。