1

我是 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
   ...
}

执行“A Problem occurred”这行后,我发现屏幕(即*screen)的内容发生了变化。

(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 是在方法 2 执行的最开始设置的。然后我在执行带有上述堆栈跟踪的“发生问题”行时遇到了第一个中断。

根据我的观察,窗口的加载似乎触发了释放 NSScreen 的 Autorelease 循环。但我没有做任何类似 autoreleasepool 的流失或释放的事情。所以我想知道为什么会这样。

最后一件事是,这个问题并不总是发生。在我的 13 和 15 英寸视网膜 MBP(OSX 10.8.2)上很容易重现此问题,但无法在我的其他 13 英寸 MBP 非视网膜(OSX10.8.2)上重现。

有人可以发表评论吗?

谢谢

4

0 回答 0