gpt4 book ai didi

objective-c - 为什么这个简单的 NSWindow 创建代码会在 ARC 下关机时触发自动释放池崩溃?

转载 作者:太空狗 更新时间:2023-10-30 03:26:05 26 4
gpt4 key购买 nike

我在关闭时遇到自动释放池崩溃的问题,我已将其简化为下面的小测试用例,它只是创建一个窗口然后将其关闭。如果移除 -fobjc-arc 标志,崩溃就会消失。在 OS X 10.8.2、Clang 4.1 (421.11.66) 上运行。我希望对 ARC 有更深入了解的人可以启发我了解这里发生的事情 - 运行僵尸对象表明它是 NSWindow 对象被释放太多次,或者没有足够保留,但是我以为 ARC 是用来处理这一切的?

堆栈跟踪是:

0   libobjc.A.dylib                 0x00007fff8fad4f5e objc_release + 14
1 libobjc.A.dylib 0x00007fff8fad4230 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 464
2 com.apple.CoreFoundation 0x00007fff99d22342 _CFAutoreleasePoolPop + 34
3 com.apple.Foundation 0x00007fff936e84fa -[NSAutoreleasePool drain] + 154
4 com.apple.Foundation 0x00007fff936effa0 _NSAppleEventManagerGenericHandler + 125
5 com.apple.AE 0x00007fff93a5ab48 aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) + 307
6 com.apple.AE 0x00007fff93a5a9a9 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 37
7 com.apple.AE 0x00007fff93a5a869 aeProcessAppleEvent + 318
8 com.apple.HIToolbox 0x00007fff8d0c18e9 AEProcessAppleEvent + 100
9 com.apple.AppKit 0x00007fff8e95c916 _DPSNextEvent + 1456
10 com.apple.AppKit 0x00007fff8e95bed2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
11 com.apple.AppKit 0x00007fff8e953283 -[NSApplication run] + 517
12 Test 0x00000001070e1d68 main + 152 (Test.mm:31)
13 libdyld.dylib 0x00007fff8e10c7e1 start + 1

测试用例的代码是:

// Tested with `clang++ -fobjc-arc -g Test.mm -framework Cocoa -o Test && ./Test`

#import <Cocoa/Cocoa.h>

@interface MyApplication : NSApplication
@end
@implementation MyApplication
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
NSWindow * window = [[NSWindow alloc] initWithContentRect: NSMakeRect(100, 100, 100, 100)
styleMask: NSTitledWindowMask backing: NSBackingStoreBuffered defer: YES];

[window close];

[super stop: self];
}
@end

int main()
{
@autoreleasepool
{
const ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);

[MyApplication sharedApplication];
[NSApp setDelegate: NSApp];

[NSApp run];
}

return 0;
}

最佳答案

使用 Instruments 的 Zombies 配置文件显示 NSWindow 对象通过调用 close: 被放入自动释放池。一旦 applicationDidFinishLaunching: 完成并销毁 NSWindow 实例,ARC 就会正确地以零引用计数结束。但是,自动释放池仍然知道现在已失效的 NSWindow 实例,然后尝试在关闭时释放它,从而导致崩溃。

在 ARC 下管理的自动释放对象似乎是个坏主意,除非自动释放池持有对其对象的归零弱引用,而这里似乎没有这样做。

可以通过添加 [window setReleasedWhenClosed: NO]; 告诉窗口在关闭时不要自动释放来防止这个问题。

关于objective-c - 为什么这个简单的 NSWindow 创建代码会在 ARC 下关机时触发自动释放池崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13345378/

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