将自定义结构中的值设置为Objective-C中的属性

时间:2014-04-24 23:45:26

标签: objective-c

我的A类标题看起来像这样:

typedef struct {
    int x;
    int y;
} Position;

@interface ClassA : NSObject

@property Position currentPosition;

@end

我尝试在另一个类中分配位置结构的各个值,如下所示:

ClassA * classA = [ClassA new];
classA.currentPosition.x = 10;

哪个错误"表达式不可分配"并且不会编译。

我可以这样设置:

ClassA * classA = [ClassA new];
Position position = {
    .x = 1,
    .y = 2
};

classA.currentPosition = position;

我甚至可以改变个人"属性"像这样的position变量:

ClassA * classA = [ClassA new];
Position position = {
    .x = 1,
    .y = 2
};

// WORKS
position.x = 4;    

// DOESN'T WORK
// classA.currentPosition.x = 4;

classA.currentPosition = position;

为什么我不能在属性时单独设置值?

2 个答案:

答案 0 :(得分:6)

这个表达式:

classA.currentPosition

返回结构的临时副本,而不是结构本身。编译器错误告诉您无法为该临时副本的某个成员分配值(因为从技术上讲它是rvalue)。但是你不想为这个成员分配一个值,因为它会随着结构本身一起消失。

那你为什么一开始只得到结构的副本呢?

因为

@property Position currentPosition

实际上只是简写:

-(Position)currentPosition;
-(void)setCurrentPosition(Position value);

并且在C系列语言中,第一行(getter)表示它返回一个Position结构的值或副本。

您可以创建自己的访问者来返回引用,但您可能不应该这样做。这不是Objective-C中常见的习语 - 至少在这种情况下不是这样 - 你通常应该尝试坚持使用语言的常用习语。

相反,你应该使用如下的位置;

Position pos = classA.position;
pos.x = 4;
classA.position = pos;

最后,如果你真的希望能够使用你最初想要的语法来设置currentPosition,那么在维护Objective-C习语的同时,你可以将Position设为一个类而不是一个struct。然后,该属性可以返回Position *,其余的语法将起作用。确保在init函数中(或在适当的时候)初始化指针。

答案 1 :(得分:2)

属性不适用于C结构。

你可以这样做:

@property Position *currentPosition;

基本上,使用指针。

现在你真的需要初始化那个指针,所以:

- (id) init {
    self = [super init];
    if(self){
        self.currentPosition = malloc(sizeof(Position));
    }
    return self;
}

然后,不要忘记使用箭头符号,因为你正在处理一个指针:

classA.currentPosition->x = 5;

不要忘记释放你要求的记忆!

-(void)dealloc{
    free(self.currentPosition);
}