1

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

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

@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指针都会指向我在其中创建的对象ClassAClassBcreateClassB3

这里发生了什么?

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

4

2 回答 2

1

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

希望它足够清楚。

于 2014-07-27T19:14:31.570 回答
1

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

于 2014-07-27T19:08:36.487 回答