如何将C结构化为类属性?

时间:2013-02-14 17:53:46

标签: ios objective-c c cocoa-touch

我有这个:

typedef struct objTag{
    float x;
    float y;
    BOOL isUP;
} object;

如何让对象成为像这样的属性

@property (nonatomic, assign) object myObj;

然后......

@synthesize myObj = _myObj;

这个编译很好,但后来在我尝试类似

的代码中
self.myObj.isUP = YES;

我收到消息“表达式不可分配”

3 个答案:

答案 0 :(得分:6)

这不起作用,因为编译器会将其编译为:

[[self getMyOj] setIsUP: YES];

您会注意到'isUP'是C结构上的属性而不是Obj-C对象ivar。

编辑:

如果你真的想要直接操纵,你需要像这样去做。

typedef struct s {
    int i;
} s;

@interface Test : NSObject {
    s *myS;
}
@property (nonatomic, assign) s *myS;
@end

@implementation Test
@synthesize myS;
- (id) init {
    self = [super init];
    myS = malloc(sizeof(s));
    myS->i = 0;
    return self;
}
@end


// somewhere later.
Test *t = [[Test alloc] init];
t.myS->i = 10;

请注意,您需要在dealloc方法中清理myS。

答案 1 :(得分:2)

这个问题回到了C编程的基础知识(即非面向对象编程)。

当您使用引用结构的属性时,您正在抓取该结构的副本,而不是对它的引用。

如果你写

CGRect rect = CGRectMake(...);
CGRect rect2 = rect;

您没有为rect2分配rect,您正在创建该结构的副本。更改rect2不会更改rect

同样,如果更改作为属性返回的结构的元素,则更改对象拥有的rect副本的元素。这可能会产生很好的 NO - 这种代码没有用处,因为你正在改变一个没有任何引用的结构元素的值。

如果您想编辑该类实际使用的结构,您的属性需要向其返回指针。这可以做到,但代码变得比它值得更加混乱:

typedef struct myObj{BOOL isUp;} TOBJECT;
...
@property (nonatomic, assign) TOBJECT* myObj; //in class interface

...

self.myObj = malloc(sizeof(TOBJECT)); //in init method.
...
self.myObj->isUp = YES; //elsewhere, even potentially outside the class.
...
free(self.myObj); //in class dealloc method.

答案 2 :(得分:0)

这就像处理UIViews上的帧一样 - 你需要一次性分配整个结构,而不是它的子值。如下所示:

object obj = self.myObj;
obj.isUP = YES;
self.myObj = obj;

如果你不喜欢它(很糟糕!),不要使用结构。相反,构建一个带有几个属性的类。结构实际上只是因为obj-c是c的超集,如果可以,你应该避免它们。 :)