多次加载笔尖后无法释放

发布于 2024-11-06 08:33:47 字数 1336 浏览 0 评论 0原文

我使用笔尖作为多个按钮的模板。看起来效果很好,他们都有自己独立的状态。然而,当我释放按钮时,我会在释放中崩溃。这是代码...

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
}

崩溃发生在对super dealloc 的调用内部,在UIButton -> 中UIButtonContent 释放。我认为我的内存管理做得很差,比如释放两次,但我不知道在哪里。

我通过多次加载笔尖所做的事情合法吗?

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

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.
Nib

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光病人 2024-11-13 08:33:47

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

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

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.

月隐月明月朦胧 2024-11-13 08:33:47

如果您使用属性并使用 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 和属性将使整个过程变得更加容易和更易于维护。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文