2011-09-01 75 views
0

zURL聲明如下:爲什麼我無法訪問此實例變量?

.H:

@interface PanelController : NSWindowController <NSWindowDelegate> 
{ 
    NSURL *zURL; 
} 

@property (nonatomic, copy) NSURL *zURL; 

.M:

@synthesize zURL; 

在一個IBAction爲我:

- (IBAction)openBrowser:(id)sender { 
    NSOpenPanel *zOpenPanel = [NSOpenPanel openPanel]; 
    [zOpenPanel setCanChooseFiles: TRUE]; 
    [zOpenPanel setCanChooseDirectories: TRUE]; 
    [zOpenPanel setAllowsMultipleSelection: TRUE]; 
    [zOpenPanel setLevel:CGShieldingWindowLevel()]; 
    NSInteger zIntResult = [zOpenPanel runModal]; 
    if (zIntResult == NSFileHandlingPanelCancelButton) { 
     return; 
    } 

    // zURL set here 
    zURL = [NSURL alloc]; 
    zURL = [zOpenPanel URL]; 
    NSLog(@"url = %@", zURL); // works 

    NSString *zStr = [zURL absoluteString]; 
    _fileField.stringValue = zStr; 
    [_importButton setEnabled:TRUE]; 
    [self openPanel]; 
} 

在接下來的IBAction爲:

NSLog(@"url = %@", zURL); // EXC_BAD_ACCESS error 
+0

你在哪裏申報zURL? –

+0

我編輯我的問題,包括喬治信息.. –

+1

首先 - 擺脫第一個[NSURL alloc]行。這是內存泄漏。第二次使用「self.zURL = [zOpenPanel URL]」。當前你直接設置實例變量的方式。使用self.zURL,您將通過將複製URL的屬性訪問器。 –

回答

2

您正在將您的URL分配給zOpenPanel的URL屬性,但未指示您打算通過保留引用來保留它。

zURL = [NSURL alloc]; // assign my variable to a new URL, allocating memory 

你的第二個行替換,以zOpenPanel的URL屬性的引用您參考,您漏水剛創建的URL。

在稍後的某個時間點,zOpenPanel通知操作系統它的URL已完成,並釋放內存,從而使您的引用無效。

什麼你可能想要做:

zURL = [[zOpenPanel URL] retain]; 

這賦予您參考zOpenPanel的URL屬性,並告訴你想擁有部分所有權的它的使用壽命操作系統。

當你與zURL做,你需要釋放並放棄您的要求在它的生命週期:

[zURL release]; 

編輯:

,因爲你宣佈它作爲你的類的屬性,你應該使用屬性標記來調用適當的行爲:

self.zURL = [zOpenPanel URL]; 

因爲你聲明的屬性,使其具有複製語義,這將複製網址,喲你仍然需要在你的dealloc中發佈它。

+0

感謝一百萬和一個。 –

0

我懷疑你的zURL var會在某個時候被釋放,正如George指出的那樣,如果你發佈了zURL的聲明,這將會很有幫助。

此外,如果立即在下一行替換zURL的值,則不需要執行[NSURL alloc]。

1

在第一行中,您正在分配NSURL,但不調用初始化程序。在第二行中,您將從另一個位置分配zURL,將指針丟棄到您在第一行創建的對象(這是內存泄漏)。

zURL存儲在哪裏?它是一個實例變量?如果是這樣,你還沒有保留從[zOpenPanel URL]返回的內容,因此無法保證該對象在IBAction中被調用時不會被釋放。

相關問題