0

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

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

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

  int hands;
  int feet;
  int legs;

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

然后,我主要从名为 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
4

1 回答 1

2

我的猜测是您没有将Body对象分配给person.body任何地方。

Objective-C 中的所有对象都分配在堆上。所有这些星号表示变量是指针,它们只是指向对象所在的内存位置的数字。当您声明一个包含对象的属性时,您真正要做的就是创建一个位置来存储指向该对象的指针。您不是在创建对象本身。

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

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

int feet = person.body.feet = 2;

...您将2同时分配给feetand person.body.feet,但是由于person.bodyis nil,因此忽略了给它的 setter 消息。稍后您再次尝试登录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,您几乎可以肯定地将该属性声明为retainnot ,并在您的方法assign中释放它。Persondealloc

于 2012-04-23T20:24:41.580 回答