0
UIAlertView* av = [UIAlertView alloc];

int a = [self somefunc];
if (a == 1) 
{
    [[av initWithTitle:nil message:@"test msg 1" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
} 
else if (a == 2) 
{
    [[av initWithTitle:nil message:@"test msg 2" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
} 

[av release];

このコードで分析を実行すると、「参照カウントされたオブジェクトは解放された後に使用されます」というエラーが次の行に表示されます。[av release];

AVがリリースされた場所を知ることができますか?UIAlertViewのshow関数はAVをリリースしましたか?

分析ツールを使用した場合、以下のコードはエラーを表示しません。

if (a == 1) 
{

    UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil message:@"test msg 1" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [av show];
    [av release];
} 

else if (a == 2) 
{
    UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil message:@"test msg 1" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [av show];
    [av release];
}
4

3 に答える 3

1

最初のコードでは、オブジェクト「av」が確実に初期化されていない場合、aの値が1 0r2でない場合はどうなりますか?avは初期化されないため、リリース時にいくつかの問題が発生します。

2番目のコードでは、avのスコープがifおよびelseの条件に対してより具体的またはローカルになりました。そのため、xcodeはavが初期化され、avを安全に解放できることを確認しています。

于 2012-11-27T10:45:13.233 に答える
1

関数は異なる値を返す可能性がinitあるため、呼び出しの戻り値を常に使用する必要があります。したがって、本当に分離しinitたい場合は、次のようにする必要があります。allocinit

UIAlertView *av = [UIAlertView alloc];
// ...
av = [av initWithTitle:...]; // Might change the value of av !!
[av show];
[av release];

コード内の「疑似リリース」は次の場所で発生します。

[av initWithTitle:...]

それは(上で説明したように)別のオブジェクトを解放avして返す可能性があるためです。

于 2012-11-27T10:57:11.700 に答える
0

show関数はUIAlertView、ここでの質問である場合 (2 番目のコード) を解放していません。

于 2012-11-27T10:46:40.130 に答える