gpt4 book ai didi

cocoa - 在 NSOperation 中自动释放对象安全吗?

转载 作者:行者123 更新时间:2023-12-03 16:19:02 25 4
gpt4 key购买 nike

我正在 NSOperationQueue 中运行 NSInvocationOperation 类型的操作,并且想知道自动释放对象是否安全 - 也就是说,是否保证为每个操作启动的线程都有自己的自动释放池。

我没有找到任何用于操作的文档自动释放池 - 阅读 Apple 的文档实际上表明我确实需要定义自己的自动释放池。

但是:1)我在仪器中看不到任何泄漏,至少不会比我在操作中分配自己的自动释放池时更多。

2)在调试器中查看我可以看到这个堆栈跟踪:

#0  0x00fc3e82 in -[NSObject(NSObject) release] ()
#1 0x00faaa6c in CFRelease ()
#2 0x00fbf804 in __CFBasicHashDrain ()
#3 0x00faabcb in _CFRelease ()
#4 0x00fcfb8d in _CFAutoreleasePoolPop ()
#5 0x000edd0d in -[__NSOperationInternal start] ()
#6 0x000ed826 in ____startOperations_block_invoke_2 ()
#7 0x94358024 in _dispatch_call_block_and_release ()
#8 0x9434a2f2 in _dispatch_worker_thread2 ()
#9 0x94349d81 in _pthread_wqthread ()
#10 0x94349bc6 in start_wqthread ()

所以看起来好像有一个 CFAutoreleasePool - 可以安全地假设该对象将在操作完成时对我所有自动释放的对象调用释放吗?

最佳答案

我编写了一个小程序来测试 NSInvocableOperation 是否会为该操作创建自动释放池:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@end

@implementation MyClass
- (void)performSomeTask:(id)data
{
NSString *s = [[[NSString alloc] initWithFormat:@"hey %@", data]
autorelease];
if ([[NSThread currentThread] isMainThread])
NSLog(@"performSomeTask on the main thread!");
else
NSLog(@"performSomeTask NOT on the main thread!");

NSLog(@"-- %@", s);
}
@end

int main(int argc, char *argv[]) {
MyClass *c = [MyClass new];

if (argc == 2 && strcmp(argv[1], "nop") == 0)
[c performSomeTask:@"ho"];
else {
NSInvocationOperation *op = [[NSInvocationOperation alloc]
initWithTarget:c
selector:@selector(performSomeTask:)
object:@"howdy"];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:op];
[op waitUntilFinished];

[op release];
[queue release];
}

[c release];

return 0;
}

它的工作原理如下:如果在命令行上传递“nop”,它将在主线程上直接执行-performSomeTask:,而没有自动释放池。结果输出是:

$ ./c nop
*** __NSAutoreleaseNoPool(): Object 0x10010cca0 of class NSCFString autoreleased with no pool in place - just leaking
performSomeTask on the main thread!
-- hey ho

-performSomeTask: 中的自动释放字符串导致泄漏。

在不传递“nop”的情况下运行程序将通过不同线程上的NSInitationOperation执行-performSomeTask:。结果输出是:

$ ./c
*** __NSAutoreleaseNoPool(): Object 0x100105ec0 of class NSInvocation autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100111300 of class NSCFSet autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100111b60 of class NSCFSet autoreleased with no pool in place - just leaking
*** __NSAutoreleaseNoPool(): Object 0x100105660 of class NSCFSet autoreleased with no pool in place - just leaking
performSomeTask NOT on the main thread!
-- hey howdy

正如我们所看到的,NSInitationNSSet 的实例正在泄漏,但 -performSomeTask 中的自动释放字符串:没有泄漏,因此为该调用操作创建了一个自动释放池。

我认为可以安全地假设 NSInitationOperation (可能还有 Apple 框架中的所有 NSOperation 子类)创建自己的自动释放池,就像并发编程指南建议的自定义那样NSOperation 子类。

关于cocoa - 在 NSOperation 中自动释放对象安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4724876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com