Search code examples
objective-cobjective-c++private-membersclass-extensions

What is the difference between declaring a member in the extended interface versus in the implementation?


I am seeing two very different behaviors for something that I thought were the exact same.

Defining my private member in the class extension like this:

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

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

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

Or defining my private member in the class implementation like this:

@interface ClassA ()
@end

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

-(ClassB*)getB
{
    return b;
}

The way I am using this code is to create a ClassB object, initialize a ClassA object with that ClassB object, and then add the ClassA object to a mutable array

-(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

When I use the first approach, and define my member in the interface extension, I see that each element in my mutable array is indeed what I would expect.

However, using the second approach, I see that my ClassB* b pointer in the ClassA object always ends up pointing to the most recently created ClassB object. That is, once the -(void)init method finishes, the ClassB pointers in each of the ClassA objects points to the ClassB object I created in createClassB3

What is happening here?

I should also mention that the ClassB object is a C++ object and this is a an objective-c++ class.


Solution

  • In your second snippet, b is just a global variable at file scope. The fact that it's inside of the @implementation ... @end is irrelevant. It is not an instance variable nor a property.