我很好奇我用工厂方法分配的内存。我的想法是,我将在一个文件中读取,并且我将通过向我的工厂方法发送单个未解析的CSV行来实例化对象,如下所示:
-(id)initWithCSV:(NSString *)csv
{
if(self = [super init])
{
NSArray *values = [csv componentsSeparatedByString:@","];
self.city = [values[0] stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
self.country = [values[1] stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
self.latitude = [values[2] doubleValue];
self.longitude = [values[3] doubleValue];
}
return self;
}
我的第一个问题是,这对内存管理有何影响?我不太清楚ARC是如何工作的。我的values
数组会在return self;
后立即销毁并退出方法,对吗?
第二个问题......有没有更有效的方法来完成我在这里要做的事情?
答案 0 :(得分:2)
关于你的第一个问题:
在这种情况下,ARC实际上没有什么区别。由于commentsSeparatedByString:
方法已经返回一个自动释放的对象,并且您没有增加它的保留计数(或者在ARC术语中,创建任何强引用),因此在方法返回时它将自动清除。
至于效率,你可以通过使用NSScanner扫描每个逗号来节省一些内存,而不是创建一个包含一串字符串的数组。但由于这只是一些相对较短的字符串,实际上它并不重要。
答案 1 :(得分:2)
TL / DR:如果你使用ARC,你的方法非常有效。
这实际上展示了ARC的一个有趣特性,与componentsSeparatedByString:
的输出是自动释放的事实有关。
说你有这个功能:
while ((line = [self readLine])) {
[self.lines addObject:[[MyObj alloc] initWithCSV:line];
}
如果没有ARC,这个看似高效的函数可能会占用大量内存,因为values
中的对象会被保留,直到自动释放池耗尽为止。 (实际上与line
相同。)优化此方法的一种传统方法是执行以下操作:
while ((line = [self readLine])) {
@autoreleasepool {
[self.lines addObject:[[MyObj alloc] initWithCSV:line];
}
}
这样,当您点击池的末尾时,将释放自动释放的values
。你当然会因为耗尽游泳池而受到性能影响。
天真的ARC实施无法解决此问题。它会看到componentsSeparatedByString:
的+0输出,调用[values retain]
并在范围结束时调用[values release]
。
ARC实际上做的是调用函数objc_retainAutoreleasedReturnValue(values)
,而不是保留values
,将其从自动释放池中删除。这样当它在作用域末尾调用[values release]
时,数组就会被释放。同样,它在我的循环的每次迭代中巧妙地释放line
。
这提供了出色的内存和CPU效率。
答案 2 :(得分:0)
我认为NSArray已发布,因为init
的范围受限于自动释放池。但是这些值会复制到self.latitude
中。