Thy*_*hys 2 iphone objective-c nsscanner automatic-ref-counting
要解析URL的部分查询字符串,我使用此方法:
NSScanner *scanner = [[NSScanner alloc] initWithString:query];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
NSString *parameterString = [NSString new];
while ([scanner scanUpToString:ampersand intoString:¶meterString])
{
NSScanner *parameterScanner = [[NSScanner alloc] initWithString:parameterString];
NSString *name = [NSString new];
[parameterScanner scanUpToString:isEqual intoString:&name];
NSString *value = [parameterString substringFromIndex:([name length] + 1)];
[parameters setObject:value forKey:name];
}
Run Code Online (Sandbox Code Playgroud)
在这个项目中我使用的是ARC,但是这个方法仍在泄漏:
[parameterScanner scanUpToString:isEqual intoString:&name];
Run Code Online (Sandbox Code Playgroud)
究竟是什么泄漏,我该如何解决?
我怀疑这个名字实际上并没有泄漏,只是当你认为它没有被释放时.在ARC下,我相信它的scanUpToString:intoString:定义与使用的方法类似NSError.换句话说,它需要NSString * __autoreleasing *.因此,传递给它的任何值实际上是自动释放的,并且在当前自动释放池耗尽之前不会释放.假设你没有任何其他点缀,那就是当运行循环再次出现时.如果内存使用对你来说是一个问题,那么就可以在循环周围放置一个显式的自动释放池,这样对象就会立即消失:
NSScanner *scanner = [[NSScanner alloc] initWithString:query];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
@autoreleasepool
{
NSString *parameterString = [NSString new];
while ([scanner scanUpToString:ampersand intoString:¶meterString])
{
NSScanner *parameterScanner = [[NSScanner alloc] initWithString:parameterString];
NSString *name = [NSString new];
[parameterScanner scanUpToString:isEqual intoString:&name];
NSString *value = [parameterString substringFromIndex:([name length] + 1)];
[parameters setObject:value forKey:name];
}
}
Run Code Online (Sandbox Code Playgroud)
这可能是不必要的,并且运行循环无论如何都会清理对象.
也就是说,仍有一个小问题意味着编译器正在为您创建一个额外的临时变量.您的name变量是隐式的__strong,因此编译器会插入一个临时变量,__autoreleasing并为您复制值.您可以通过明确声明NSString为自动释放来避免这种情况.你也不需要init它,正如rckoeness所说的那样,因为scanUpToString:intoString:它正在为你做这件事(这就是为什么它必须__autoreleasing在第一位).(有关详细信息,请参阅http://developer.apple.com/library/mac/ipad/#releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html).
所以,总的来说,我认为你实际上希望你的代码看起来像这样:
NSScanner *scanner = [[NSScanner alloc] initWithString:query];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
NSString __autoreleasing *parameterString = nil;
while ([scanner scanUpToString:ampersand intoString:¶meterString])
{
NSScanner *parameterScanner = [[NSScanner alloc] initWithString:parameterString];
NSString __autoreleasing *name = nil;
[parameterScanner scanUpToString:isEqual intoString:&name];
NSString *value = [parameterString substringFromIndex:([name length] + 1)];
[parameters setObject:value forKey:name];
}
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!
我有另一个想法,也许name只是一个红鲱鱼.泄漏将显示分配发生的位置,但name在此循环之后继续存在,当它被添加到parameters.我认为它是一个NSMutableDictionary或类似的,基于选择器.如果我是你,我会确认name实例没有被泄露,因为该字典(或后来从字典中读取这些键的东西)被泄露.
| 归档时间: |
|
| 查看次数: |
1688 次 |
| 最近记录: |