动态的c风格数组.什么时候使用retain,什么时候释放,什么时候执行



根据我的最后一个问题,我决定从一个简单的类开始包含二维数组数据。

接口:

@interface DynamicTable
NSString ***data;
NSInteger _cols;
NSInteger _rows;
@end

初始化:

-(id)initWithRows:(NSInteger)rows withCols:(NSInteger)cols {
    if (self = [super init]) {
        _rows = rows;
        _cols = cols;
        data = (NSString ***)malloc(_rows * sizeof(NSString **));
        for (int i = 0; i < _rows; ++i) {
            data[i] = (NSString **)malloc(_cols * sizeof(NSString *));
            for (int j = 0; j < _cols; ++j) {
                NSString *cell = [[NSString alloc] initWithFormat:@"%d",(i + j)];
                data[i][j] = cell;
            }
        }
    }
    return self;
}

我们保留还是不保留?
此时此刻,我正在与一位学员(他之前为iPhone开发过,而我没有)进行激烈的讨论,是否分配的任务data[I][j] = cell;不应该是data[I][j] = [cell retain];。第二个版本来自于SO的另一个样品。我从同一个问题中复制了dealloc例程。

在赋值时释放吗?
下一段代码负责在给定单元格中设置新值。再次出现是否释放原始值的问题(我已经认为它都是通过引用传递的)。

-(void)setValue:(NSString *)value atRow:(NSInteger)row atCol:(NSInteger)col {
    //NSString *cell = data[row][col];
    data[row][col] = value;
    //[cell release];
}

正如你所看到的,我已经注释掉了应该释放原始值的位。

iPhone的整个内存管理似乎相当可怕。我已经在苹果网站和其他网站上读了很多关于这方面的文章,但要一下子消化太多了。有清晰解释的小例子通常最适合我LOL

回到我的问题:
从我的角度来看(不确定我是否正确),我应该释放放入给定单元格的原始值。有人能确认我的方向是对的吗?

PS我一直在尝试使用运行性能工具->泄漏…但在这方面,我对iPhone知识的缺乏也阻碍了我的发展。

我同意David的观点,坚持使用Objective-C但我会回答你最初的问题,因为这可能有助于你过渡到Objective-C。

第一个例子做得很好。下面的代码返回一个保留的字符串,因为您调用了alloc/init。

NSString *cell = [[NSString alloc] initWithFormat:@"%d",(i + j)];
data[i][j] = cell;

您的dealloc调用将类似于此

-(void)dealloc
{
    for(int i = 0; i < _rows; ++i)
    {
        for(int j = 0; j < _cols; ++j)
        {
            [data[i][j] release];
        }
        free(data[i]);
    }
    free(data);
    [super dealloc];
}

现在对于第二个示例,您需要保留该值,但同时释放前一个值。

-(void)setValue:(NSString *)value atRow:(NSInteger)row atCol:(NSInteger)col {
    [value retain]; //retain in case value is the same
    [data[row][col] release];
    data[row][col] = value;
}

我不认为内存管理在Objective-C中是可怕的,实际上只有一些基本的规则需要遵循,很少有例外(-[NSAutoreleasePool drain]浮现在脑海中)。

您正在尝试在objective-c环境中编写一些c代码。如果我是你,我会坚持使用objective-c并且很少使用c。这是在objective-c中看起来的样子。

@interface DynamicTable
NSMutableArray *data;
NSInteger _cols;
NSInteger _rows;
@end
-(id)initWithRows:(NSInteger)rows withCols:(NSInteger)cols 
{
    if (self = [super init]) 
    {
        _rows = rows;
        _cols = cols;
        data = [[NSMutableArray alloc] init]; //Release in dealloc method
        for (int i = 0; i < _rows; ++i) 
        {
            NSMutableArray *cells = [NSMutableArray array]; //Auto released
            for (int j = 0; j < _cols; ++j) 
            {
                NSString *cell = [[NSString alloc] initWithFormat:@"%d",(i + j)];
                [cells addObject:cell]; //Auto retains
                [cell release]; //Release
            }
            [data addObject:cells];
        }
    }
    return self;
}

这是你在访问器中要做的。

-(void)setValue:(NSString *)value atRow:(NSInteger)row atCol:(NSInteger)col 
{
    [[data objectAtIndex:row] insertObject:value atIndex:col]; //Auto retained
}

最新更新