我使用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非常简单,它只包含父视图和自定义视图类型的子视图。
cSoundButton只是跟踪名称和布尔状态静音或不静音。这是dealloc
- (void)dealloc {
delete[] mSoundTag;
// Call the inherited implementation
[super dealloc]; //****Crashes in here
}
崩溃是在UIButton的超级dealloc调用内 - &gt; UIButtonContent dealloc。我假设我在做内存管理方面做的事情很糟糕,比如两次解除分配,但我无法发现在哪里。
通过多次加载笔尖是合法的,我正在做什么?
答案 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
和属性将使整个过程更加容易和可维护。