1

まったく同じだと思っていたものに対して、2 つの非常に異なる動作が見られます。

次のように、クラス拡張でプライベート メンバーを定義します。

@interface ClassA ()
@property ClassB* b;
@end

@implementation ClassA
-(ClassA*)initWithClassB:(ClassB*)newB
{
    self.b = newB;
    return self;
}

-(ClassB*)getB
{
    return self.b;
}

または、クラス実装でプライベート メンバーを次のように定義します。

@interface ClassA ()
@end

@implementation ClassA
ClassB* b;
-(ClassA*)initWithClassB:(ClassB*)newB
{
    b = newB;
    return self;
}

-(ClassB*)getB
{
    return b;
}

私がこのコードを使用している方法は、ClassB オブジェクトを作成し、その ClassB オブジェクトで ClassA オブジェクトを初期化し、次に ClassA オブジェクトを可変配列に追加することです。

-(void)init
{
    self.classAList = [[NSMutableArray alloc] init];
    [self.classAList addObject:[[ClassA alloc] initWithClassB:[self createClassB1]]];
    [self.classAList addObject:[[ClassA alloc] initWithClassB:[self createClassB2]]];
    [self.classAList addObject:[[ClassA alloc] initWithClassB:[self createClassB3]]];
}
-(ClassB)createClassB1
{
    ClassB* classB = new ClassB();
    //do some init
    return classB;
}
// Same thing fore createClassB2 and createClassB3 except with different data

最初のアプローチを使用して、インターフェイス拡張でメンバーを定義すると、可変配列の各要素が実際に期待どおりであることがわかります。

ただし、2 番目の方法を使用するClassB* bと、オブジェクト内のポインターがClassA常に最後に作成されたオブジェクトを指していることがわかりClassBます。つまり、-(void)initメソッドが終了すると、ClassB各オブジェクトのポインターは、作成しClassAたオブジェクトを指します。ClassBcreateClassB3

ここで何が起きてるの?

また、ClassB オブジェクトは C++ オブジェクトであり、これは目的の C++ クラスであることにも言及する必要があります。

4

2 に答える 2

1

2 番目のスニペットでbは、ファイル スコープの単なるグローバル変数です。の中にあるという事実@implementation ... @endは無関係です。インスタンス変数でもプロパティでもありません。

于 2014-07-27T19:08:36.487 に答える
1

2 番目のアプローチでは、グローバル変数を作成します。つまり、それは ClassA のどのインスタンスにも関連付けられていないため、メモリ内の同じオブジェクトを指す *b の同じインスタンスが常に 1 つ存在します。したがって、 *b の値を変更するたびに、 b 変数が指しているメモリ内のオブジェクトを変更していますが、新しいオブジェクトを作成することはありません。よりよく理解するために、基本的にすべての ClassA オブジェクトを同じ ClassB 変数 (*b) で初期化しているため、*b が指しているメモリの部分の値を変更すると、すべてのインスタンスに対して値が変更されます。クラスAの作成。

それが十分に明確であることを願っています。

于 2014-07-27T19:14:31.570 に答える