3
- (NSString *)allocString{
    NSString *str = [[NSString alloc] init];
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self allocString];

    [name release]; // Can I release an object here?
}

こんにちは、NSString を使用して簡単な例を書きました。私の実際のプログラムでは、NSString の代わりにカスタム UIView クラスを使用しました。

allocString は 1 つの NSString インスタンスを作成し、その保持カウントは 1 です。自動解放がなければ、インスタンスを返すだけです。

viewDidLoad メソッドでは、変数「name」は allocString メソッドによって返されたオブジェクトを指すだけなので、インスタンスの保持カウントは 1 のままです。

したがって、[name release] は保持カウントを減らします。

これは正しいですか?または、allocString メソッドで自動解放する必要がありますか? ありがとうございました!

4

3 に答える 3

6

あなたがしたことはうまくいくでしょう。retainすべてが均等になる限り、選択した任意のスコープからオブジェクトを取得できreleaseます (そして、オブジェクトが他のオブジェクトで不要になったときにオブジェクトの割り当てが解除されます)。

しかし、あなたがしていることは慣習的ではありません。オブジェクトがメソッドの存続期間を過ぎても存続できるようにする場合 (returnメソッドの呼び出し元がオブジェクトを取得できるようにするため)、 を使用する必要がありますautorelease

あなたの例では、最初のメソッドはおそらく文字列の所有権を保持すべきではありません。それを解放し、発信者がそれを拾うことができるようにする必要があります。ただし、もちろん、releaseメソッドでそれを行うと、すぐに割り当てが解除されます。代わりに、それを行うことができautoreleaseます。それを自動解放することにより、最初の方法は「このオブジェクトは不要になり、所有権を放棄しますが、必要に応じて呼び出し元が保持できるように、もう少しの間メモリに保持してください」と言います

次に例を示します。

- (NSString *)createString {
    /* Create a string. This method owns it. */
    NSString *str = [[NSString alloc] init];

    /* Autorelease it. This method does not own it, but wants it to stay in memory temporarily. */
    [str autorelease]

    /* Return it. It will stay in memory till the end of the current run loop */
    return str;
}

- (void)viewDidLoad{
    NSString *name = [self createString];
    /* We now have a copy of the string. Nobody owns it. */
    /* It is due to be released at the end of the current run loop. */

    /* If we want to take ownership of it and prevent deallocation, we should retain it. */
    [name retain];
}

この動作は、Cocoa API 全体で使用されます。新しいオブジェクトを返すクラス メソッドが表示されると、そのオブジェクトは自動解放されます。たとえば、呼び出す[NSArray arrayWithObjects:@"One", @"Two", @"Three", nil]ときは、NSArray クラスに配列を作成するように依頼しています。arrayWithObjects:自動解放ステータスのおかげで、メソッドの外部に存在する場合。そうしないretainと、現在の実行ループの最後に解放されます。

于 2011-03-29T04:39:23.053 に答える
1

「allocString」メソッド名を「newString」に置き換えるだけで、正常に機能します。このようなメソッドを処理するためのObjectiveCの規則があります。その規則では、メソッド名は「new *」で始まる必要があり、メモリリークは発生しません。

于 2011-03-29T05:20:24.573 に答える
0

はい、そこにあるものはすべてうまく機能します。

于 2011-03-29T04:14:29.140 に答える