2013-10-25 31 views
4

我有一個應用程序使用多個模態表單進行數據輸入。打開模式表的方法運行良好,並且仍然正常工作,但它們已被棄用,我擔心它們很快就不能用於未來的Xcode版本。 Here, Apple points out how to use modal sheets打開10.9的模態表格

- (void)showCustomSheet: (NSWindow *)window 

// User has asked to see the custom display. Display it. 
{ 
    if (!myCustomSheet) 
//Check the myCustomSheet instance variable to make sure the custom sheet does not already exist. 
     [NSBundle loadNibNamed: @"MyCustomSheet" owner: self]; 

    [NSApp beginSheet: myCustomSheet 
      modalForWindow: window 
      modalDelegate: self 
      didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) 
      contextInfo: nil]; 

    // Sheet is up here. 
    // Return processing to the event loop 
} 

但在Xcode 5.1的發佈,他們確定了loadNibNamed方法已經過時,我們應該使用類似功能指引頂級對象。

我遇到的問題,正在改變這一點:

[NSBundle loadNibNamed:@"OrderDetailsWindow" owner:self]; 

到這一點。

NSArray *array; 
[[NSBundle mainBundle]loadNibNamed:@"OrderDetailsWindow" owner:self topLevelObjects:&array]; 

此方法調用確實會打開模態表單。但是,在我的方法結束時,打開模式表單,Xcode掛起這個錯誤。

0x7fff8c33b097: andl 24(%r11), %r10d Thread1: EXC_BAD_ACCESS (code:EXC_I386_GPFLT) 

我不確定這是告訴我什麼。它在調試區域中沒有提供任何信息。這可能與topLevelObjects數組未正確釋放有關嗎?有關如何使這項工作更順利一點的想法?蘋果過時的圖書館讓我瘋狂!

+0

您使用的是Xcode 5.1嗎? –

+0

是的,我正在使用5.1。 – Breeze73

+2

如果您使用的是Xcode 5.1,那麼您必須在Apple工作。我們其餘的人都在使用Xcode 5.0.1。僅供參考 - 您的問題與Xcode無關。任何棄用的東西都與Cocoa框架的API版本有關。 – rmaddy

回答

4

是的,蘋果的文檔是一團糟。 「圖紙編程主題」文檔自2009年以來未更新。

更改後不顯示完整代碼,但我的猜測是您的問題與您的NIB對象的內存管理有關。

從新loadNibNamed:owner:topLevelObjects:

不同於傳統方法的文檔,對象堅持標準可可內存 管理規則;有必要通過使用IBOutlets或保持對數組的引用來保持對它們的強烈引用 以防止 nib內容被重新分配。

對頂層對象的出口應該強烈參考 以證明所有權並防止重新分配。

你有NSArray,它擁有方法中的頂級對象。一旦執行離開這個方法,NSArray將被取消和釋放,如果這些對象在其他地方沒有強烈引用,那麼所有頂級對象都將被釋放和釋放。

您需要將NIB中的頂層對象連接到Window控制器中的出口,或將NSArray作爲Window Controller實例的成員變量保存,以便在您的工作表顯示方法退出時不會被釋放。並確保myCustomSheet從工作表的NIB正確聲明和連接。

此外,[NSApp beginSheet:]也被棄用,您現在致電beginSheet on an instance of NSWindow

+0

回覆良好。我認爲這正是我遇到的問題。我會亂它,看看我能否得到它的工作。 – Breeze73

0

我總是用一個NSWindowController子與我的牀單自定義委託:

從想要顯示板的窗口:模態窗口控制器內然後

_myModalController = [[MyModalController alloc] init]; 
_myModalController.delegate = self; 
[_myModalController beginSheet:self.window]; 

,我有:

- (id)init { 
    self = [super initWithWindowNibName:@"MyModalWindow" owner:self]; 
    return self; 
} 

- (void)beginSheet:(NSWindow *)mainWindow { 
    [NSApp beginSheet:[self window] 
     modalForWindow:mainWindow 
     modalDelegate:self 
     didEndSelector:@selector(_didEndSheet:returnCode:contextInfo:) 
      contextInfo:nil]; 
} 

- (void)endSheet:(NSWindow *)mainWindow { 
    [NSApp endSheet:[self window]]; 
    [[self window] orderOut:mainWindow]; 
} 

這似乎是爲了避免loadNibNamed:已被棄用的問題。

+0

並非所有的loadNibNamed形式都被棄用,需要使用當前的形式。 [NSApp beginSheet]和[NSApp endSheet]已棄用10.9 – danielv

+0

@danielv嗯,沒有看到。雖然沒有來自Xcode的警告(但是我的min-macosx版本是10.7,所以也許這就是爲什麼)。我想知道我還在使用什麼已被棄用... – trojanfoe

+0

您使用10.9 SDK還是設置爲指向較舊的SDK? – danielv