#import不使用2个类之间的继承

时间:2012-04-23 19:34:18

标签: objective-c

请帮助理解#import如何在不使用继承的情况下工作。

所以我创建了一个名为Person的类和另一个名为Body的类(这两个类都是从NSObject继承而来的)。

Body类有3个ivars(使用属性设置)

  int hands;
  int feet;
  int legs;

然后我导入并创建了Body类(* body)的实例到Person类中。我的理解是我现在已经从Body类中创建了一个“类型”。然后将这个ivar设置为属性。

在main中,我然后从名为person的Person类创建了一个实例。 Main识别person.body.feet但我无法直接获取并设置其值。它可以做的唯一方法是将其值传递给新的int变量,然后打印出新的变量。

显然我是一个苦苦挣扎的新人,但我真的很想了解这个问题 -

  #import <Foundation/Foundation.h>
    #import "Person.h"

    int main (int argc, const char * argv[])
    {

        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

        Person *person = [[Person alloc]init];

        // this works and NSLog prints out the value is 2
        int feet = person.body.feet = 2;
        NSLog(@"person.body = %i",feet);


        // this does not work - NSLog prints out the value is 0; 
        [person.body setFeet:2];
        NSLog(@"person.body = %i", person.body.feet );



        [person release];
        [pool drain];
        return 0;
    }

    #import <Foundation/Foundation.h>
#import "Body.h"

@interface Person : NSObject {

    Body *body;

}

   @property (assign) Body *body;

@end


#import "Person.h"

@implementation Person

  @synthesize  body;

@end


#import <Foundation/Foundation.h>

@interface Body : NSObject {

    int hands;
    int feet;
    int legs;

}

@property int hands;
@property int feet;
@property int legs;

@end



#import "Body.h"

@implementation Body

@synthesize hands;
@synthesize feet;
@synthesize legs;


@end

1 个答案:

答案 0 :(得分:2)

我的猜测是你没有在Body任何地方分配person.body个对象。

Objective-C中的所有对象都在堆上分配。所有这些星号都表示变量是指针,指针只指向对象所在的内存位置。当您声明一个包含对象的属性时,您所做的只是创建一个存储指向该对象的指针的位置。您不是自己创建对象。

所以某处(最有可能在Person指定的初始化程序中),您需要实际创建一个Body对象并将其分配给body属性。

如果你这样做,那么内存位置将保持在0,相当于nil。当您在此处链接作业时:

int feet = person.body.feet = 2;

...您正在为2feet分配person.body.feet,但由于person.bodynil,因此忽略了设置者的消息。稍后您尝试再次登录person.body.feet时,它将nil并返回nil / 0

编辑:查看了您的更新,是的,这是您的问题。

此行不会创建Body对象:

Body *body;

它为指向 Body对象的指针创建一个实例变量。

此行不会创建Body对象:

@property (assign) Body *body;

它声明了一个属性,它是getter和setter方法声明的语法糖。

此行不会创建Body对象:

@synthesize  body;

它通过创建getter和setter方法来合成先前声明的属性。

您需要实际创建并初始化Body对象,然后将其分配给Person对象的body属性。例如:

- (id)init {
    if (self = [super init]) {
        self.body = [[Body alloc] init];
    }
    return self;
}

此外,由于您没有使用ARC,您几乎肯定会声明该属性为retain而不是assign,并在Person的{​​{1}}中释放它方法。