1

次のコードについて明確にする必要があります。

ClassA オブジェクトを含む配列があります。次に、そのオブジェクトの 1 つを取得し、それをローカル変数 object1 に割り当てます。

 ClassA object1 = [ClassAObjectContainer objectAtIndex:0];

( Q.1 - これは保持数を増やしますか?? 私はそうではないと思います )

今、私はオブジェクトを削除します

  [ClassAObjectContainer removeObjectAtIndex:0];

( Q.2 - object1 は割り当て解除されたインスタンスを指すようになりましたか?? メッセージを送信するとクラッシュしますか??

だから私は ClassA object1 = [[ClassAObjectContainer objectAtIndex:0] preserve]; を使用する必要があります。オブジェクトを生かしておき、後で使用したい場合。

オブジェクトがメソッドから返されるときのより良いアプローチはどれですか

- (ClassA *)calle
{
    ClassA *object1 = [[ClassA alloc] init];
    return [object1 autorelease];
}

- (void)Caller
{
    ClassA *object2 = [self calle];
    //now suppose object1 is auto-released, so in this case object2 points to deallocated instance?
}

だったらいいじゃないか――

- (void)CallerMethod
{
    ClassA *object2 = [[self calle] retain];
   // Do other works.
   /.....

    [object2 release];
}

この場合に起こった別のこと、

- (ClassA *)calle2
    {
        ClassA *object1 = [[ClassA alloc] init];
        return [object1 autorelease];
    }


 - (void)CallerMethod
    {
        ClassA *object2 = [self calle];

        object2 = [self calle2];

    }

ここでメモリ リークがありますか、それとも ClassA *object2 = [self calle] が weak/assign であるため、2 回目の初期化 object2 = [self calle2] の後は問題ありません。この方法で 100 個のオブジェクトを割り当てることができ、メモリ リークは発生しません。

御時間ありがとうございます。

4

2 に答える 2

3

ここに答えがあります

Q1: いいえ。単純割り当てのretainCountに変更はありません。

Q2: Index のオブジェクトの ratainCount に依存します。つまり、配列から削除されると、retainCount が 1 減ります。削除後にretainCount が 0 になると、クラッシュが発生します。それ以外の場合は発生しません。

AutoRelease: メソッド (new/copy 以外) によって返される自動解放されたオブジェクトを使用する際の黄金律は、それを保持することです。作業が完了したら、リリースする必要があります。必要な数の初期化を行うことができますが、作成されたすべてのオブジェクトで autorlase プールが過負荷になる可能性があります。

于 2013-02-18T06:35:43.110 に答える
2

Q.1 - これは保持数を増やしますか?? そうじゃないと思う

必ずしもそうではありませんが、一時的に増加する可能性があります。objectAtIndex:couldの実装retainと、それautoreleaseを返す前のオブジェクトの実装。

Q.2 - object1 が割り当て解除されたインスタンスを指すようになりましたか?? メッセージを送信すると、クラッシュしますか??

-objectAtIndex:上記のように、自動解放されたオブジェクトを返すように注意しないと、そうなる可能性があります。疑いがある場合は、コンテナーからオブジェクトを削除する前に、オブジェクトを自分で保持する必要があります。したがって、たとえば、のドキュメントに-[UIView removeFromSuperView]は次のように記載されています。

ビューを再利用する予定がある場合は、このメソッドを呼び出す前にビューを保持し、必要に応じて後で再度解放してください。

それはまさにスーパービューがビューを解放するからです。保持していない場合は、その時点で割り当てが解除される可能性があります。

だから私は ClassA object1 = [[ClassAObjectContainer objectAtIndex:0] preserve]; を使用する必要があります。オブジェクトを生かしておき、後で使用したい場合。

「後で」使用したい場合は、確かにそれを保持する必要があります。「今」使用する場合は、オブジェクトの内容によっては、オブジェクトを保持する必要がない場合がありますClassAObjectContainer

あなたの質問の残りの部分に従っているかどうかわかりません。ただし、一般に、オブジェクトを他のメソッドから取得した場合、そのオブジェクトを取得したメソッドの終了後も保持する予定がない限り、そのオブジェクトを保持せずに使用できるはずです。したがって、インスタンス変数などに割り当てる場合は、 を呼び出してオブジェクトの所有権を取得する必要がありますretain。コレクションの動作は少し複雑です。コレクションからオブジェクトを取得し、そのコレクションにオブジェクトを削除するように指示した場合、削除後に必要になる場合は、最初にオブジェクトを保持する必要があることを実際に期待する必要があります。 . 一方、ARC を使用している場合 (なぜ使用しないのですか?)、そのようなことを心配する必要はありません。

于 2013-02-18T06:35:42.037 に答える