gpt4 book ai didi

iphone - 使用 ARC 时 NSScanner scanUpToString 泄漏

转载 作者:行者123 更新时间:2023-12-03 20:20:09 24 4
gpt4 key购买 nike

要解析 URL 的查询字符串的一部分,我使用此方法:

NSScanner *scanner = [[NSScanner alloc] initWithString:query];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];

NSString *parameterString = [NSString new];
while ([scanner scanUpToString:ampersand intoString:&parameterString])
{
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];


}

在这个项目中我使用了 ARC,但该方法仍然在这一行泄漏:

[parameterScanner scanUpToString:isEqual intoString:&name];

到底是什么泄漏以及如何解决这个问题?

最佳答案

我怀疑这个名字实际上并没有泄露,它只是在你认为的时候没有被发布。在 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:&parameterString])
{
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];


}
}

但这可能是不必要的,无论如何运行循环都会清除对象。

也就是说,仍然存在一个小问题,这意味着编译器正在为您创建一个额外的临时变量。您的 name 变量隐式为 __strong,因此编译器会插入一个名为 __autoreleasing 的临时变量,并为您复制值。您可以通过显式声明 NSString 为 autoreleasing 来避免这种情况。正如 rckoeness 所说,您也不需要 init 它,因为 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:&parameterString])
{
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];
}

希望有帮助!

<小时/>

我有另一个想法,也许name只是一个转移注意力的东西。泄漏将显示分配发生的位置,但当将 name 添加到 parameters 时,该名称将继续存在于该循环之外。根据选择器,我认为它是一个 NSMutableDictionary 或类似的。如果我是你,我会确认 name 实例没有被泄露,因为该字典(或稍后从字典中读取这些键的东西)正在被泄露。

关于iphone - 使用 ARC 时 NSScanner scanUpToString 泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8820158/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com