在扩展接口和实现中声明成员之间有什么区别?

时间:2014-07-27 18:56:57

标签: objective-c objective-c++ private-members class-extensions

对于我认为完全相同的事情,我看到了两种截然不同的行为。

在类扩展中定义我的私有成员,如下所示:

@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

当我使用第一种方法,并在接口扩展中定义我的成员时,我看到我的可变数组中的每个元素确实是我所期望的。

但是,使用第二种方法,我发现ClassB* b对象中的ClassA指针始终指向最近创建的ClassB对象。也就是说,一旦-(void)init方法完成,每个ClassB对象中的ClassA指针指向我在ClassB createClassB3对象>

这里发生了什么?

我还应该提到ClassB对象是一个C ++对象,这是一个Objective-c ++类。

2 个答案:

答案 0 :(得分:1)

在第二个代码段中,b只是文件范围内的全局变量。它在@implementation ... @end内的事实无关紧要。它不是实例变量也不是属性。

答案 1 :(得分:1)

使用第二种方法,您将创建一个全局变量,这意味着它与ClassA的任何实例都无关,因此您将始终拥有一个同一个* b实例指向内存中的同一个对象。因此,每当你改变* b的值时,你都在改变b变量所指向的内存中的对象,但从不创建新的对象;为了更好地理解它你基本上用同一个ClassB变量(即* b)初始化每个ClassA对象,所以如果你改变* b所指向的内存部分的值,你就会为所有实例改变它创建了ClassA。

希望它足够清楚。