1

我在追踪此内存泄漏错误时遇到了一些麻烦Potential leak of an object allocated on line...

@interface BNPieChart : UIView {
@private
    NSMutableArray* slicePointsIn01;
}

m
- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initInstance];
        self.frame = frame;        
        slicePointsIn01 = [[NSMutableArray alloc]
                       initWithObjects:nFloat(0.0), nil];       

- (void)initInstance {
    slicePointsIn01 = [[NSMutableArray alloc]
                       initWithObjects:nFloat(0.0), nil];

我确实尝试添加一个属性/合成/释放,slicePointsIn01但是这给了我同样的错误。

我究竟做错了什么 ?

4

1 回答 1

4

slicePointsIn01被设置为两个不同的对象:一个在 中initInstance,然后一个在initWithFrame:.

因为第一个被设置为一个alloc'd 对象,所以在您更改分配之前该对象从未存在release过,原始对象被泄露。

如果您添加一个属性,您需要确保您实际使用它,而不是直接使用实例变量。您可以通过以下两种方式之一进行分配来做到这一点:

self.myProperty = //something;
[self setMyProperty: //something];

注意(感谢@André):确保something对象在分配时保留计数为 0(即通常是自动释放),因为属性会为您保留它。

//NOT like this:
myProperty = //something;

此行直接使用实例变量。它会导致您的泄漏,因为不使用该属性,指向的对象的引用计数不会改变。

编辑: 你不应该检查保留计数。只需在使用对象的每个地方都遵守规则,就可以了。以下是规则:

  • 您通过为它分配内存或复制它来拥有您创建的任何对象,即使用方法alloc, allocWithZone:, copy, copyWithZone:, mutableCopy,mutableCopyWithZone:

  • 如果您不是对象的创建者,但希望确保它保留在内存中供您使用,您可以通过调用来表达对它的所有权权益retain

  • 如果您拥有一个对象,无论是通过创建它还是表达所有权权益,您都有责任在不再需要它时释放它,方法是调用releaseautorelease

  • 相反,如果您不是对象的创建者并且没有表达所有权权益,则不得释放它。

  • 如果您从程序的其他地方收到一个对象,通常保证它在接收它的方法或函数中保持有效。如果您希望它在该范围之外保持有效,您应该保留或复制它。如果你试图释放一个已经被释放的对象,你的程序就会崩溃。

你不必写setMyProperty。当您@synthesize拥有一个属性时,就会为您创建该方法。

于 2011-11-11T09:17:12.457 回答