开发者

Failing to Release after Multiple Nib loads

I am using a Nib as a template for several buttons. It seemed to work fine, they each have their own independent state. However when I went to release the buttons I would crash in the dealloc. Here is the code...

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 's开发者_如何学CoundNib'

    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;
}

Header:

@interface cLocationContext {
   ...

   cSoundButton** mSoundBtns;
   IBOutlet cSoundButton* soundNib;

}

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

@end

The Nib is very simple, it just include a parent view and a child view of a custom view type.

Failing to Release after Multiple Nib loads

cSoundButton simply keeps track of a name and a boolean state Mute or Not. Here is the dealloc

- (void)dealloc {

    delete[] mSoundTag;

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

The crash is inside the call to super dealloc, in UIButton -> UIButtonContent dealloc. I assume I am doing something poor with my memory management like deallocing twice but I can't spot where.

Is what I am doing by loading the nib multiple times legal?


You have to retain the button as soon as you load it from the NIB. If you don't, you are not allowed to release it later, and you won't be able to access the button once your code returns control to the runloop (when the autorelease pool is drained).

PS: Wouldn't it be easier to use a Cocoa collection (NSMutableArray) to store the references to the buttons? Your code looks too complicated to me.


It will greatly simplify your memory management if you use your property and use an NSArray to store the button instances.

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

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

Later, when it's time to release

[mSoundBtns release];

Keep in mind that when you're using properties you've got to reference them through self. The following two lines are exactly equivalent:

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

When you set soundNib = nil you are setting the variable soundNib to nothing, losing the reference to the button you loaded. If you hadn't added the pointer to an array and released it later you'd be leaking everything. Technically the way you're doing it might work... but don't do it that way. Using proper NSArrays and properties will make this whole process significantly easier and more maintainable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜