【问题标题】:What is the difference between declaring a member in the extended interface versus in the implementation?在扩展接口中声明成员与在实现中声明成员有什么区别?
【发布时间】:2014-07-27 18:56:56
【问题描述】:

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

像这样在类扩展中定义我的私有成员:

@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

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

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

这里发生了什么?

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

    • 我注意到当我将b 放入{ } 中时@implementation...@end 我得到了与第一种方法相同的行为,这是为什么?
    • 是的。实例变量总是在@interface@implementation 中的大括号内。请注意,实例变量和属性(这是您的第一个 sn-p 中的 b)不是一回事。
    【解决方案2】:

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

    希望它足够清楚。

    【讨论】:

      猜你喜欢
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多