私は OSX 開発者です。私が遭遇した問題は以下のように説明されています:
- (void)method1:(NSObject *)arg1
contextInfo:(NSObject *)arg2
{
...
[self method2:arg1
screen:[self.windowController window].screen];
...
}
- (void)method2:(NSObject *)arg1
screen:(NSScreen *)screen
{
...
MyWindowController *myWindowController =
[[MyWindowController alloc] initWithWindowNibName:@"MyWindow"];
NSWindow *aWindow = [MyWindowController window]; // A Problem happens
...
}
「問題が発生しました」という行を実行した後、画面の内容 (つまり、*画面) が変更されていることがわかりました。
(gdb) p *screen
$15 = {
<NSObject> = {
isa = 0x7fff788a6598 xxxxxxxx changed
},
members of NSScreen:
_frame = {
origin = {
x = -4353346, xxxxxxx changed
y = -234234
},
size = {
width = -35252435, xxxxxxxx changed
height = -3452663, xxxxxxxx changed
}
},
_depth = 520,
_screenNumber = 2077752383,
_auxiliaryStorage = 0x0
}
最初は、スタック オーバーフローまたはメモリ破損が原因でこの問題が発生した可能性があると考えていました。しかし、その後、gdb を使用して *screen が変更されたときを監視しました。また、メモリ破損が原因で、予期せず画面が解放されたのではないかと思いました。だから私もスクリーンと*スクリーンを見ました。しかし、私が得たのはそれだけです:
(コードの一部をここで公開できないため、一部のログを変更していることをお許しください。)
#0 0x00007fff8427824f in objc_msgSend ()
#1 0x00007fff8c5748e4 in -[NSScreen dealloc] ()
#2 0x00007fff8581528a in CFRelease ()
#3 0x00007fff85852efc in -[__NSArrayI dealloc] ()
#4 0x00007fff8427c230 in (anonymous namespace)::AutoreleasePoolPage::pop ()
#5 0x00007fff8583cd72 in _CFAutoreleasePoolPop ()
#6 0x00007fff8c07c172 in loadNib ()
#7 0x00007fff8c07b88c in +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] ()
#8 0x00007fff8c1ce5bc in +[NSBundle(NSNibLoading) loadNibFile:externalNameTable:withZone:] ()
#9 0x00007fff8c20160b in -[NSWindowController loadWindow] ()
#10 0x00007fff8c2012e5 in -[NSWindowController window] ()
#11 0x000000010003c3c9 in -[SessionListener method2:screen:] (self=0x10220caa0, _cmd=0x100261922, arg1=0x10209ede0, screen=0x1020b7d20) at SessionListener.m:307
#12 0x000000010003d3f4 in -[SessionListener method1:contextInfo:] (self=0x10220caa0, _cmd=0x1002618a0, arg1=0x10206b950, arg2=0x0) at SessionListener.m:457
rwatch と watch は、実行中の method2 の最初に設定されました。次に、上記のスタック トレースを使用して「問題が発生しました」という行を実行しているときに、最初のブレークが発生しました。
私の観察によると、ウィンドウの読み込みは、NSScreen を解放する Autorelease サイクルをトリガーするように見えました。しかし、autoreleasepool のドレインやリリースのようなことは何もしませんでした。だから、どうしてこうなったんだろうと思いました。
最後に、この問題は常に発生するとは限りません。この問題は、13 および 15 インチの Retina MBP (OSX 10.8.2) では非常に簡単に再現できますが、他の 13 インチ MBP 非 Retina (OSX10.8.2) では再現できません。
誰でもコメントを残すことができますか?
ありがとう