多个Nib加载后无法释放

时间:2011-05-11 18:08:48

标签: iphone objective-c memory-management refcounting

我使用Nib作为几个按钮的模板。它似乎工作正常,他们每个人都有自己独立的状态。然而,当我去释放按钮时,我会在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非常简单,它只包含父视图和自定义视图类型的子视图。 Nib

cSoundButton只是跟踪名称和布尔状态静音或不静音。这是dealloc

- (void)dealloc {

    delete[] mSoundTag;

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

崩溃是在UIButton的超级dealloc调用内 - &gt; UIButtonContent dealloc。我假设我在做内存管理方面做的事情很糟糕,比如两次解除分配,但我无法发现在哪里。

通过多次加载笔尖是合法的,我正在做什么?

2 个答案:

答案 0 :(得分:3)

从NIB加载按钮后,您必须立即保留该按钮。如果不这样做,则不允许以后释放它,并且一旦代码将控制权返回到runloop(当自动释放池耗尽时),您将无法访问该按钮。

PS:使用Cocoa集合(NSMutableArray)来存储对按钮的引用会不会更容易?你的代码对我来说太复杂了。

答案 1 :(得分: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和属性将使整个过程更加容易和可维护。