考虑以下方法和调用者代码块。该方法分析NSString
并提取一个"http://"
字符串,它通过引用传递出来作为自动释放对象。
不发布g_scan_result
,程序按预期工作。但根据非弧规则,g_scan_result
应该被释放,因为已经调用了保留。
我的问题是:
g_scan_result
无法释放?g_scan_result
的方式有什么不对吗?g_scan_result
? 希望知识渊博的人可以提供帮助。
- (long) analyse_scan_result :(NSString *)scan_result target_url :(NSString **)targ_url {
NSLog (@" RES analyse string : %@", scan_result);
NSRange range = [scan_result rangeOfString:@"http://"
options:NSCaseInsensitiveSearch];
if (range.location == NSNotFound) {
*targ_url = @"";
NSLog(@"fnd string not found");
return 0;
}
NSString *sub_string = [scan_result substringFromIndex : range.location];
range = [sub_string rangeOfString : @" "];
if (range.location != NSNotFound) {
sub_string = [sub_string substringToIndex : range.location];
}
NSLog(@" fnd sub_string = %@", sub_string);
*targ_url = sub_string;
return [*targ_url length];
}
以下是调用者代码块,还要注意g_scan_result已声明并初始化(在另一个源文件上):
NSString *g_scan_result = nil;
如果您有建议或在此处(或上方)发布的代码中发现可能的错误,请发送评论或回答。 Xcode内存工具似乎没有显示任何内存泄漏。但这可能是因为我不知道在哪里看起来像是记忆工具的新手。
{
long url_leng = [self analyse_scan_result:result target_url:&targ_url];
NSLog(@" TAR target_url = %@", targ_url);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Scanned Result"
message:result
delegate:g_alert_view_delegate
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
if (url_leng) {
// ****** The 3 commented off statements
// ****** cannot be added without causing
// ****** a crash after a few scan result
// ****** cycles.
// ****** NSString *t_url;
if (g_system_status.language_code == 0)
[alert addButtonWithTitle : @"Open"];
else if (g_system_status.language_code == 1)
[alert addButtonWithTitle : @"Abrir"];
else
[alert addButtonWithTitle : @"Open"];
// ****** t_url = g_scan_result;
g_scan_result = [targ_url retain];
// ****** [t_url release];
}
targ_url = nil;
[alert show];
[alert release];
[NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(activate_qr_scanner:)
userInfo:nil
repeats:NO
];
return;
}
答案 0 :(得分:0)
我认为这个谜团已经解决了。感谢所有善意的人。原因是在添加UIAlertView之前,已完成编码(在另一个源文件上)以将原始输出字符串分配给g_scan_result并直接在当前视图上显示它。因此,当g_scan_result被释放时,它会释放由某些过时代码分配的错误NSString。
总之,发布了错误的NSString,这是问题的根源。
解决方案只是删除一个过时的语句。旧实现的声明留在那里,因为我认为它不会造成任何伤害(甚至可能有助于使变量连续填充)。但事实证明这是一个非常愚蠢的错误。唯一的借口是最近很少睡觉。找个借口确实有用。只是希望它不必经常完成......