请帮助理解#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
答案 0 :(得分:2)
我的猜测是你没有在Body
任何地方分配person.body
个对象。
Objective-C中的所有对象都在堆上分配。所有这些星号都表示变量是指针,指针只指向对象所在的内存位置。当您声明一个包含对象的属性时,您所做的只是创建一个存储指向该对象的指针的位置。您不是自己创建对象。
所以某处(最有可能在Person
指定的初始化程序中),您需要实际创建一个Body
对象并将其分配给body
属性。
如果你不这样做,那么内存位置将保持在0
,相当于nil
。当您在此处链接作业时:
int feet = person.body.feet = 2;
...您正在为2
和feet
分配person.body.feet
,但由于person.body
为nil
,因此忽略了设置者的消息。稍后您尝试再次登录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}}中释放它方法。