不规则形状的UIButton中的内存泄漏

时间:2010-10-09 20:30:57

标签: iphone memory-leaks uinavigationcontroller uibutton

我知道这是一个长镜头,但由于我需要这个代码才能工作,也许这里有人可以提供帮助。

我在我的一个iPhone应用程序中使用CodeProject.com的Irregularly Shaped Buttons代码。效果很好,但是仪器报告了两次内存泄漏。我正在使用标准UIViewController中的代码,但这是在UINavigationController中,这可能是问题所在。

clickThruButton.m

的myInit方法中报告了第一个泄漏
- (void) myInit
{
    // Set so that any alpha > 0x00 (transparent) sinks the click
    uint8_t threshold = 0x00;
    self.alphaMask = [[AlphaMask alloc]  initWithThreshold: threshold]; 
    [self setMask];
}

我可以看到下面的版本,所以我不确定为什么会泄漏:

- (void)dealloc
{
    [self.alphaMask release];
    [super dealloc];
}

也许我们首先需要检查一下self.alphaMast在执行alloc之前是否为nil?

第二个是 AlphaMask.m 中calcHitGridFromCGImage方法的结尾:

// COPIES buffer
// is AUTORELEASED!
// http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/
// MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH
NSData* ret = [NSData dataWithBytes: (const void *) dest 
                             length: (NSUInteger) destBytes ];

CGContextRelease (alphaContext);
free (alphaGrid);
free (dest);

return ret;

泄漏出现在NSData分配上。没有分配,新的或复制,所以泄漏在哪里?

我会真的感谢您在这里提供的任何帮助。我知道这是一个延伸,但我需要这个尽快工作。谢谢!

更新:

可以在上面的链接中找到完整的源代码,但这可能有助于清除alphaMask定义:

//
//  ClickThruButton.h
//  Test
//
//  Pi

@class AlphaMask;

@interface clickThruButton : UIButton 
{
    @private AlphaMask* _alphaMask;
}

@end

和...

//
//  ClickThruButton.m
//  Test
//
//  Pi

#import "clickThruButton.h"
#import "AlphaMask.h"

@interface clickThruButton ()

@property (nonatomic, retain) AlphaMask* alphaMask;

- (void) myInit;
- (void) setMask;

@end

@implementation clickThruButton

@synthesize alphaMask = _alphaMask;

2 个答案:

答案 0 :(得分:3)

<强>(1)

alphaMask属性可能设置为-retain。这会导致保留计数在设置时自动增加1。但[AlphaMask alloc]已经返回一个保留计数为+1的对象,因此整体保留计数过多+2。

[self.alphaMask release]之后只能将保留计数减少1,所以最后计数不能达到0并解除分配,即内存将被泄露。

您应该将其重写为

AlphaMask* mask = [[AlphaMask alloc]  initWithThreshold: threshold];
self.alphaMask = mask;
[mask release];        // cancel the retain.

<强>(2)

我不认为这段代码有任何泄漏。

答案 1 :(得分:0)

self.alphaMask = [[AlphaMask alloc] initWithThreshold: threshold];可能是泄密。虽然没有看到该属性的定义,但我无法肯定地说。