3

まず、これがかなり基本的な質問である場合はお詫びしますが、私はObjective Cの初心者であり、すべての検索で質問に対する答えを見つけることができませんでした(ただし、これは私が初心者ではないためかもしれません)答えを探している間、正しい用語をかなり使用しています!)

単純なループがあり、その中にいくつかのカスタムオブジェクトをNSMutableArrayに入力します。私が見つけたのは、ループの後に、要素がすべて同じ値を持っているように見える配列があることです。つまり、(0,1,2,3)を挿入した後、配列に(3,3,3,3)が含まれていることがわかります。 。

この問題は、オブジェクトを使用している場合にのみ発生します。文字列のみを追加する2番目の配列には、期待値が入力されます。

配列内のオブジェクトのアドレスを見ると、それらはすべて異なっていることがわかります。これは、同じオブジェクトを参照するポインターの配列がないことを意味すると考えるのは正しいですか?

なぜこれが期待どおりに動作しないのかを理解したいと思います。非常に基本的なものが欠けているような気がしますので、どんな洞察もいただければ幸いです。

これは私が実行するループです:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"STARTING");
    NSMutableArray* myArray1 = [NSMutableArray array];
    NSMutableArray* myArray2 = [NSMutableArray array];

    for (int i=0; i < 4; i++) {
        MyObject* obj = [[MyObject alloc] initWithSomeString: [NSString stringWithFormat: @"ID%u", i] 
                                                  AndSomeNum: i];
        [myArray1 addObject: obj];
        [myArray2 addObject: [NSString stringWithFormat: @"ID%u", i]];

        NSLog(@"  Added to array1: %@", [myArray1 objectAtIndex: i]);
        NSLog(@"       and array2: %@", [myArray2 objectAtIndex: i]);
    }

    NSLog(@"ALL DONE:\nARRAY1=%@\nARRAY2=%@", myArray1, myArray2);
}

これを実行した後に得られる出力は次のとおりです。

STARTING
   Added to array1: num=0 self=<0x928e9b0> str=<0x9290090> str=ID0
        and array2: ID0
   Added to array1: num=1 self=<0x9290080> str=<0x928ff80> str=ID1
        and array2: ID1
   Added to array1: num=2 self=<0x928eb00> str=<0x9290020> str=ID2
        and array2: ID2
   Added to array1: num=3 self=<0x7499a30> str=<0x7499ae0> str=ID3
        and array2: ID3
ALL DONE:
ARRAY1=(
    "num=3 self=<0x928e9b0> str=<0x7499ae0> str=ID3",
    "num=3 self=<0x9290080> str=<0x7499ae0> str=ID3",
    "num=3 self=<0x928eb00> str=<0x7499ae0> str=ID3",
    "num=3 self=<0x7499a30> str=<0x7499ae0> str=ID3"
)
ARRAY2=(
    ID0,
    ID1,
    ID2,
    ID3
)

これは、MyObjectクラスの実装です。

@implementation MyObject

NSString* _blah;
int _num;

-(MyObject*)initWithSomeString: (NSString*)blah AndSomeNum: (int)num {
    self = [super init];
    _blah = [NSString stringWithString: blah];
    _num = num;
    return self;
}

-(NSString*)description {
    return [NSString stringWithFormat: @"num=%u self=<%p> str=<%p> str=%@", _num, self, _blah, _blah];
}

@end
4

1 に答える 1

4

ここでの問題は、これら2つの変数の定義です。

NSString* _blah;
int _num;

これらをこのファイルに配置すると、グローバル変数として定義されます。したがって、クラスのすべてのインスタンスは、これらの同じ2つの変数を共有しています。これが、初期化子を呼び出すたびに、同じ「_blah」が上書きされる理由です。

それらをインスタンス変数にするつもりで、各インスタンスが独自の「_blah」と「_num」を持っている場合は、クラスの実装またはインターフェースの{}内でそれらを宣言する必要があります。したがって、これは例として機能します。

@implementation MyObject {

 NSString* _blah;
 int _num;

} // continue with method definitions...
于 2013-01-15T04:32:11.623 に答える