0

次のメソッドと呼び出し元のコードブロックについて考えてみます。このメソッドはaを分析し、自動解放オブジェクトとして参照によって渡される文字列をNSString 抽出します。"http://"

リリースしなくg_scan_resultても、プログラムは期待どおりに動作します。しかし、非アークルールによればg_scan_result、保持がそれに反対して呼び出されたので、解放されるべきです。

私の質問は:

  1. なぜg_scan_result解放できないのですか?
  2. g_scan_result以下の投稿されたコーディングで処理される方法に何か問題がありますか?
  3. g_scan_resultプログラムが正しく実行され、XCodeメモリリークツールがリークを示さない限り、 リリースしないのは安全ですか?
  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がリリースされました。

解決策は、1つの古いステートメントを削除することです。古い実装からのステートメントは、害を及ぼさないと思ったのでそこに残されました(そして、変数を継続的に設定するのに役立つかもしれません)。しかし、それは非常にばかげた間違いであることが判明しました。唯一の言い訳は、最近ほとんど睡眠をとっていないことです。言い訳を見つけることができることは目的を果たします。頻繁に行う必要がないことを願っています...

于 2012-11-03T08:23:58.067 に答える