无法释放NSString

时间:2012-11-02 16:49:21

标签: objective-c nsstring

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

不发布g_scan_result,程序按预期工作。但根据非弧规则,g_scan_result应该被释放,因为已经调用了保留。

我的问题是:

  1. 为什么g_scan_result无法释放?
  2. 在下面的已发布编码中处理g_scan_result的方式有什么不对吗?
  3. 只要程序正常运行且XCode内存泄漏工具没有显示泄漏,是否安全不释放g_scan_result
  4. 我应该查看哪些XCode配置文件工具以查看哪个副标题?
  5. 希望知识渊博的人可以提供帮助。

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

1 个答案:

答案 0 :(得分:0)

我认为这个谜团已经解决了。感谢所有善意的人。原因是在添加UIAlertView之前,已完成编码(在另一个源文件上)以将原始输出字符串分配给g_scan_result并直接在当前视图上显示它。因此,当g_scan_result被释放时,它会释放由某些过时代码分配的错误NSString。

总之,发布了错误的NSString,这是问题的根源。

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