简体   繁体   中英

Objective C Array elements all ending up with same values

Firstly, an apology if this is a rather basic question, however I am a newcomer to Objective C and I have not been able to find an answer to my question in all of my searches (although this may well be because I am a novice not quite using the correct terminology while looking for an answer!)

I have a simple loop, inside of which I populate an NSMutableArray with some custom objects. What I find is that after the loop, I have an array whose elements all seem to have the same values: ie after inserting (0,1,2,3) I find that my array contains (3,3,3,3).

The problem is only present when using my objects; a second array, into which I add only strings, ends up populated with the expected values.

Looking at the addresses of the objects in my array, I see that they are all different: am I correct in thinking that this means that I do not simply have an array of pointers that reference the same object?

I am wanting to understand why this is not behaving as I expected. I have a feeling that there is something quite basic that I am missing, and any insights would be greatly appreciated.

This is the loop that I execute:

- (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);
}

The output that I get after running this is:

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
)

This is the implementation of the MyObject class:

@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

The issue here is your definition of these two variables:

NSString* _blah;
int _num;

Where you have them placed in this file, they are defined as global variables. So every instance of your class is sharing these same two variables. This is why each time you call your initializer, the same '_blah' is being overwritten.

If you meant for them to be instance variables, each instance having its own '_blah' and '_num', then you need to declare them within {} in the implementation or interface for your class. So this would work as an example:

@implementation MyObject {

 NSString* _blah;
 int _num;

} // continue with method definitions...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM