2011-05-11 46 views
1

我使用筆尖作爲幾個按鈕的模板。它似乎工作正常,他們每個人都有自己的獨立國家。但是,當我釋放按鈕時,我會在dealloc中崩潰。下面是代碼...未能在多個筆尖加載後發佈

mSoundBtns = new cSoundButton*[mNumSounds]; 
for(unsigned int i = 0 ; i < mNumSounds; ++i) { 
    mSoundBtns[i] = nil; 
} 

for(unsigned int s = 0; s < mNumSounds; ++s) { 

    [[NSBundle mainBundle] loadNibNamed:@"InstanceSoundButton" owner:self options:nil]; 
    //Auto Loads via Outlet into 'soundNib' 

    mSoundBtns[s] = soundNib; 
    soundNib = nil; 

    uint32 count = mSoundBtns[s].retainCount; 
    NSLog(@"Last Count: %d", count); 
} 


for(unsigned int j = 0; j < mNumSounds; ++j) { 
    [mSoundBtns[j] release]; //**** Crash here on 7th (of 8) release 
    mSoundBtns[j] = nil; 
} 

頁眉:

@interface cLocationContext { 
    ... 

    cSoundButton** mSoundBtns; 
    IBOutlet cSoundButton* soundNib; 

} 

@property (nonatomic, assign) IBOutlet cSoundButton* soundNib; 

@end 

筆尖很簡單,它只是包括父視圖和自定義視圖類型的子視圖。 Nib

cSoundButton只是跟蹤名稱和布爾狀態靜音或不靜音。這裏是的dealloc

- (void)dealloc { 

    delete[] mSoundTag; 

    // Call the inherited implementation 
    [super dealloc]; //****Crashes in here 
} 

崩潰是調用超級的dealloc裏面,UIButton的 - > UIButtonContent的dealloc。我假設我在執行內存管理方面做得很差,例如兩次釋放,但我無法找到位置。

正是我通過多次加載筆尖合法的做法?

+1

** retainCount **沒用。別叫它。 – bbum 2011-05-12 03:54:05

回答

3

只要您從NIB加載按鈕,您就必須保留該按鈕。如果你不這樣做,你不能在以後發佈它,並且一旦你的代碼返回控制權給runloop(當autorelease池被排空時),你將無法訪問按鈕。

PS:使用Cocoa集合(NSMutableArray)來存儲對按鈕的引用不是更容易嗎?你的代碼對我來說太複雜了。

1

如果您使用屬性並使用NSArray來存儲按鈕實例,它將大大簡化您的內存管理。

[[NSBundle mainBundle] loadNibNamed:@"InstanceSoundButton" owner:self options:nil]; 
//Auto Loads via Outlet into 'soundNib' 

[mSoundBtns addObject:self.soundNib]; 
self.soundNib = nil; 

後來,當它的時間來釋放

[mSoundBtns release]; 

請記住,當你使用你得通過self引用它們的屬性。下面兩行是完全等價的:

self.soundNib = something; 
[self setSoundNib:something]; 

當您設置soundNib = nil要設置變量soundNib不了了之,失去了參考您加載的按鈕。如果您沒有將指針添加到數組並稍後將其釋放,則會泄漏所有內容。從技術上講,你這樣做的方式可能會奏效......但不要那樣做。使用適當的NSArray和屬性將使整個過程變得更容易和更易於維護。