baD*_*aDa 1 iphone cocoa-touch objective-c
我需要检查一下特定的位置,NSArray看看它们是否已经初始化,但我遇到了麻烦.我尝试执行以下操作,但它会导致我的应用程序崩溃!
if ((NSMutableArray *)[arrAllBlocks objectAtIndex:iLine] == nil)
{
[arrAllBlocks insertObject:[[NSMutableArray alloc] init] atIndex:iLine];
}
NSMutableArray *columArray = (NSMutableArray *)[arrAllBlocks
objectAtIndex:iLine];
[columArray insertObject:newBlock atIndex:iColumn];
Run Code Online (Sandbox Code Playgroud)
这样做最好的是什么?我已经尝试了一些像这样的方法isValid!
你有几个选择:
选项1:使用实例预填充数组NSNull,然后使用Dave DeLong在其答案中给出的代码.
选项2 :(类似于#1)使用实例预先填充数组NSMutableArray,然后根本没有额外的代码.(如果你要预先填写,你也可以这样做).
选项3:不要预先填充数组,而是根据需要动态插入项目.如果第一个iLine接近最大值,这几乎与预填充相同:
while([arrAllBlocks count] <= iLine)
{
[arrAllBlocks addObject:[NSMutableArray arrayWithCapacity:0]];
}
NSMutableArray *columArray = (NSMutableArray *)[arrAllBlocks
objectAtIndex:iLine];
[columArray insertObject:newBlock atIndex:iColumn];
Run Code Online (Sandbox Code Playgroud)
选项4:使用字典维护以下列表NSMutableArrays:
NSString *key = [NSString stringWithFormat:@"%d", iLine];
NSMutableArray *columnArray = [dictAllBlocks objectForKey:key];
if (columnArray == nil)
{
columnArray = [NSMutableArray arrayWithCapacity:0];
[dictAllBlocks setObject:columnArray forKey:key];
}
[columArray insertObject:newBlock atIndex:iColumn];
Run Code Online (Sandbox Code Playgroud)
如何选择:
如果最大值iLine不是很大,我会选择#2.少数NSMutableArrays初始化为零的容量将占用很少的内存.
如果最大值iLine是巨大的,但是你希望它被稀疏地访问(即,只会访问几个值iLine),那么你应该使用选项#4.这将使您不必填充NSMutableArray永远不会被使用的对象.转换字典的字符串值键的开销将小于创建所有这些空格的开销.
如果您不确定,请尝试每个选项并对其进行分析:测量内存使用情况和执行所需的时间.如果这些选项都不起作用,您可能需要探索更复杂的解决方案,但只有在必要时才这样做.
注意事项:
您发布的原始代码在以下行中有内存泄漏:
[arrAllBlocks insertObject:[[NSMutableArray alloc] init] atIndex:iLine];
Run Code Online (Sandbox Code Playgroud)
NSMutableArray您在此处初始化的对象永远不会被释放.当您致电时[[NSMutableArray init] alloc],会创建一个全新的对象(引用计数为1).该insertObject方法然后添加新对象到arrAllBlocks,并且retains它(增加其保留计数到2).稍后,当您释放时arrAllBlocks,新数组将被发送一条release消息,但这只会将其保留计数再次减少为一.此时,它将一直存在于RAM中,直到程序退出.
这里最好的办法是使用[NSMutableArray arrayWithCapacity:0](就像我在我的例子中所做的那样).这将返回一个新的NSMutableArray,就像你的代码一样,但是这个实例已经存在了autoreleased.这样,arrAllBlocks可以获得新对象的所有权,并且可以确保它将在适当时释放.
| 归档时间: |
|
| 查看次数: |
772 次 |
| 最近记录: |