从使用NSArray
动态构建数组的方法返回NSDictionary
(或NSMutableArray
等)时,执行此操作的标准方法是什么,并避免使用ARC时随机内存泄漏?
例如,假设我们有一些带有名称列表的类,我们想手动过滤并获取以给定字母开头的所有名称:
- (NSArray *)getNamesByFirstLetter:(NSString *)firstLetter
{
NSMutableArray *returnValue = [[NSMutableArray alloc] init];
for(id item in self.names)
{
if([item hasPrefix:firstLetter])
{
[returnValue addObject:item];
}
}
return returnValue; // just return the above array
}
当谈到返回值时,我可以想到四种可能的方法:
直接返回NSMutableArray
(如上所述)
return returnValue;
返回copy
return [returnValue copy];
使用NSArray arrayWithArray
返回
return [NSArray arrayWithArray:returnValue];
创建NSArray
,手动将NSMutableArray
设置为nil
:
NSArray *temp = [NSArray arrayWithArray:returnValue]; // could use [returnValue copy] here too
returnValue = nil;
return temp;
当一个程序使用ARC时,这四种方法之间是否有任何真正的区别,还是仅归结为个人偏好?
此外,除了可能的内存泄漏之外,使用一种方法而不是另一种方法还有其他影响吗?
注意,如果这是重复的,请告诉我,我会把问题记下来。我尝试过搜索,但很难将问题缩小到几个搜索字词。
答案 0 :(得分:9)
启用ARC后,所有四个选项都可以正常使用(即您提出的解决方案都不会导致内存泄漏)。
但是,您概述的4种解决方案略有不同。数字1将返回NSMutableArray
,这可能不会导致问题,因为NSMutableArray
将响应与NSArray
相同的所有消息(但返回的对象将是可变的,您可能不会要)。
选项2和选项3&之间存在细微差别。 4(在ARC下相同)。如果returnValue
为nil
,则选项2将返回nil
,但选项3& 4将返回空NSArray
。 (这两种行为都是可取的;你应该决定你希望这种方法的行为方式)。此外,-copy
可能比+arrayWithArray
更快。
我会选择2。
答案 1 :(得分:3)
首先要说的是:您讨论的所有方法都不会导致ARC下的内存泄漏。此外,第四种方法不要求您将returnValue
设置为nil
- 编译器足够聪明,可以自行处理returnValue
。这使得第四个方法与第三个方法完全相同。
此外,在copy
上调用returnValue
与从其内容创建新数组相同,因此第二种方法与后两种方法相同。
这给我们留下了两种方法 - 第一种,第二种/第三种/第四种。它们之间的主要区别在于用户可以使用他从方法中获取的数组。第一种方法是让用户修改数组;最后三个没有。决定你更喜欢哪种行为取决于你。
答案 2 :(得分:0)
在给定示例中没有泄漏的一点是,每个人都知道NSArray 可能是可变的。如果您是方法调用的结果,那么无论您是复制它还是按原样使用它,都可以随时更改它。这就是为什么不可变属性通常被声明为副本而不是强大的原因。为该属性分配可变值将执行实际复制,并且分配不可变值很便宜。
tl; dr:只返回returnValue,没关系。