在NSMutableArray类别中泄漏,返回填充NSNull的数组

时间:2011-04-13 16:44:53

标签: iphone ios memory-management memory-leaks

我目前有一个NSMutableArray类别,用于创建使用NSNulls传播的NSMutableArray。当我在Instruments中运行此代码时,它告诉我这里有泄漏(阅读评论以查看位置)

#import "NSMutableArray+NSNull.h"


@implementation NSMutableArray (NSNull)

-(id)initWithNullCapacity:(int)capacity{

    self = [super init];
    if (self) {
        //Leak on [self init]
        NSMutableArray *array = [self init];

        for (unsigned i = 0; i < capacity; i++)
        {
            [array addObject:[NSNull null]];
        }
        self = array;
    }
    return self;
}

修改

这是我调用方法的地方:

#import "TWVStatData.h"
#import "NSMutableArray+NSNull.h"

@implementation TWVStatData

@synthesize creationTime;
@synthesize graphs;
@synthesize elements;
@synthesize type;

-(id)init{
    if(self == [super init]){
        type = -1;

        creationTime = [[NSDate alloc] init];

        graphs = [[NSMutableArray alloc] initWithNullCapacity:3];
        elements =[[NSMutableArray alloc] init];
    }
    return self;
}

4 个答案:

答案 0 :(得分:3)

这将是棘手的,主要是因为NSArray在下面的工作方式。我建议这样做:

- (id)initWithNullCapacity:(NSUInteger)capacity {
  NSMutableArray *nulls = [NSMutableArray array];
  for (NSUInteger i = 0; i < capacity; i++) {
    [nulls addObject:[NSNull null]];
  }
  return [self initWithArray:nulls];
}

我认为问题源于对self的分配,尽管我不确定。 NSArray做了一些时髦的优化,所以我会避免在之后之前调用NSArray初始化程序,准备好所有数据。

答案 1 :(得分:2)

是的,因为第一行

self = [super init];

您正在创建一个对象(self),而self = array;您正在取消引用self并重新分配它。所以早期的价值是泄漏。

答案 2 :(得分:2)

你没有创建一个NSMutableArray的子​​类,只是添加一个类别,因此调用[super init]将调用NSArray而不是NSMutableArray初始化器,无论它是什么,我会调用以防万一它做了重要的事情。

另外,正如Ravin所说,设置self =而不首先调用[self release]会泄漏上一个对象,该对象在调用堆栈中从alloc调用返回一层。

这是你应该做的:

-(id)initWithNullCapacity:(int)capacity
{
    self = [self initWithCapacity:capacity];
    if (self) 
    {
        for (int i = 0; i < [self count]; i++)
        {
            [self addObject:[NSNull null]];
        }
    }
    return self;
}    

答案 3 :(得分:1)

-(id)initWithNullCapacity:(int)capacity
{
    self = [super init];
    if (self) {
        for (unsigned i = 0; i < capacity; i++)
        {
            [self addObject:[NSNull null]];
        }
    }
    return self;
}

应该做的工作