ios block(5)
来源:未知 责任编辑:责任编辑 发表时间:2015-09-17 09:44 点击:次
p>
p>
p>通过这种手法,block 就不会持有 self 的引用,从而打破了循环引用。
p>
p>
p>
p>
p>
p>扩展:其他还需要注意避免循环引用的地方
p>
p>
p>与此类似的情况还有 NSTimer。苹果官方文档中提到"Note in particular that run loops retain their timers, so you can release a timer after you have added it to a run loop.",同时在对接口
p>
p>
p>+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
p>的 target 说明文档中提到:
p>
p>
p>The object to which to send the message specified by aSelector when the timer fires. The target object is retained by the timer and released when the timer is invalidated.
p>结合这两处文档说明,我们就知道只要重复性 timer 还没有被 invalidated,target 对象就会被一直持有而不会被释放。因此当你使用 self 当作 target 时,你就不能期望在 dealloc 中 invalidate timer,因为在 timer 没有被invalidate 之前,dealloc 绝不会被调用。因此,需要找个合适的时机和地方来 invalidate timer,但绝不是在 dealloc 中。
p>
p>
p>
p>
p>
p>4,block 内存管理分析
p>
p>
p>block 其实也是一个 NSObject 对象,并且在大多数情况下,block 是分配在栈上面的,只有当 block 被定义为全局变量或 block 块中没有引用任何 automatic 变量时,block 才分配在全局数据段上。 __block 变量也是分配在栈上面的。
p>
p>
p>在 ARC 下,编译器会自动检测为我们处理了 block 的大部分内存管理,但当将 block 当作方法参数时候,编译器不会自动检测,需要我们手动拷贝该 block 对象。幸运的是,Cocoa 库中的大部分名称中包含”usingBlock“的接口以及 GCD 接口在其接口内部已经进行了拷贝操作,不需要我们再手动处理了。但除此之外的情况,就需要我们手动干预了。
p>
p>
p>
p>[cpp]
p>- (id) getBlockArray
p>{
p> int val = 10;
p> return [[NSArray alloc] initWithObjects:
p> ^{ KSLog(@" > block 0:%d", val); }, // block on the stack
p> ^{ KSLog(@" > block 1:%d", val); }, // block on the stack
p> nil];
p>
p>// return [[NSArray alloc] initWithObjects:
p>// [^{ KSLog(@" > block 0:%d", val); } copy], // block copy to heap
p>// [^{ KSLog(@" > block 1:%d", val); } copy], // block copy to heap
p>// nil];
p>}
p>
p>
p>- (void)testManageBlockMemory
p>{
p> id obj = [self getBlockArray];
相关新闻>>
最新推荐更多>>>
- 发表评论
-
- 最新评论 更多>>