0

考虑以下方法和调用者代码块。该方法分析 aNSString 并提取"http://"它通过引用传递的字符串作为自动释放对象。

在没有发布的情况g_scan_result下,该程序按预期工作。但是根据非弧规则,g_scan_result应该释放,因为已经针对它调用了保留。

我的问题是:

  1. 为什么g_scan_result不能释放?
  2. g_scan_result下面发布的编码中的处理方式有什么问题吗?
  3. g_scan_result只要程序运行正确且 XCode Memory Leak 工具不显示泄漏, 不释放是否安全?
  4. 我应该检查哪些 XCode 配置文件工具以及在哪个字幕下检查?

希望有知识的人可以帮忙。

- (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;
}
4

1 回答 1

0

我想谜团已经解开了。感谢所有愿意对此进行调查的人。原因是在添加 UIAlertView 之前,已完成编码(在另一个源文件上)以将原始输出字符串分配给 g_scan_result 并将其直接显示在当前视图上。因此,当 g_scan_result 发布时,它正在释放由一些过时代码分配的错误 NSString。

总之,错误的 NSString 被释放,这是问题的根源。

解决方案只是删除一个过时的语句。旧实现中的语句保留在那里,因为我认为它不会造成任何伤害(甚至可能有助于使变量不断填充)。但事实证明这是一个非常愚蠢的错误。唯一的借口就是最近睡得很少。能够找到借口确实是有目的的。只是希望它不必经常这样做......

于 2012-11-03T08:23:58.067 回答