Max*_*ler 25 nsoperation nsautoreleasepool ios automatic-ref-counting ios8
我已阅读并发编程指南
在指南中,文本指出GCD调度队列定义了他们自己的@autoreleasepool池,并提到仍然建议在每个调度级别定义一个,但是对于NSOperation没有说什么,Apple提供的示例代码也没有显示@autoreleasepool结构.在NSOperation的背景下,模糊地提到@autoreleasepool的唯一地方是修订历史,
2012-07-17 - 删除了有关自动释放池使用操作的过时信息.
查看在线提供的示例代码,例如 http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues在基于NSOperations的对象的实现中使用@autoreleasepool,例如:
@implementation ImageDownloader
- (void)main {
@autoreleasepool {
...
}
}
@end
Run Code Online (Sandbox Code Playgroud)
Stu*_*nie 36
如果您从NSOperation该main方法派生并实现该方法,则无需设置自动释放池.该start方法的默认实现推送NSAutoReleasePool,调用main然后弹出NSAutoReleasePool.同样适用于NSInvocationOperation和NSBlockOperation,它们共享相同的start方法实现.
以下是该start方法的简略反汇编NSOperation.注意调用NSPushAutoreleasePool,然后调用main,然后调用NSPopAutoreleasePool:
Foundation`-[newMyObj__NSOperationInternal _start:]:
0x7fff8e5df30f: pushq %rbp
...
0x7fff8e5df49c: callq *-0x16b95bb2(%rip) ; (void *)0x00007fff8d9d30c0: objc_msgSend
0x7fff8e5df4a2: movl $0x1, %edi
; new NSAutoreleasePool is pushed here
0x7fff8e5df4a7: callq 0x7fff8e5df6d6 ; NSPushAutoreleasePool
... NSOperation main is called
0x7fff8e5df6a4: callq *-0x16b95dba(%rip) ; (void *)0x00007fff8d9d30c0: objc_msgSend
0x7fff8e5df6aa: movq %r15, %rdi
; new NSAutoreleasePool is popped here, which releases any objects added in the main method
0x7fff8e5df6ad: callq 0x7fff8e5e1408 ; NSPopAutoreleasePool
Run Code Online (Sandbox Code Playgroud)
以下是一些运行示例代码的快照
MyObj在main方法中分配,我确保对象必须自动释放main返回到_start,并且下图显示了MyObj dealloc当前自动释放池调用的堆栈跟踪,弹出内部_start
作为参考,这是我用来验证行为的示例代码:
#import <Foundation/Foundation.h>
@interface MyObj : NSObject
@end
@implementation MyObj
- (void)dealloc {
NSLog(@"dealloc");
}
@end
@interface TestOp : NSOperation {
MyObj *obj;
}
@end
@implementation TestOp
- (MyObj *)setMyObj:(MyObj *)o {
MyObj *old = obj;
obj = o;
return old;
}
- (void)main {
MyObj *old = [self setMyObj:[MyObj new]];
[self setMyObj:old];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
NSOperationQueue *q = [NSOperationQueue new];
TestOp *op = [TestOp new];
[q addOperation:op];
[op waitUntilFinished];
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据并发编程指南,Grand Central Dispatch类似地管理调度队列的自动释放池:
如果您的块创建了多个Objective-C对象,您可能希望将块的代码部分包含在@autorelease块中,以处理这些对象的内存管理.尽管GCD调度队列具有自己的自动释放池,但它们无法保证这些池何时耗尽.如果您的应用程序受内存限制,则创建自己的自动释放池允许您以更加规则的间隔释放自动释放对象的内存.
| 归档时间: |
|
| 查看次数: |
2391 次 |
| 最近记录: |