Objective-C 结构定义和修改给出错误“表达式不可分配”?

Posted

技术标签:

【中文标题】Objective-C 结构定义和修改给出错误“表达式不可分配”?【英文标题】:Objective-C struct definition and modification gives error 'Expression not assignable'? 【发布时间】:2015-05-08 17:40:36 【问题描述】:

我一直在阅读其他类似的问题,但这些解决方案要么不适合我们,要么无法解决我手头的问题。我的代码实际上很简单,我不知道该怎么做。好的:

在 .h 文件中我有:

struct MyState
    float quantizer;
    BOOL isOpen;
;

@interface ... 
    ...
    struct MyState myState;


@property (nonatomic,assign) struct MyState myState;

在 .m 文件中,我进行了诸如以下的读写操作:

@synthesize myState

...
self.myState.isOpen = TRUE;
if(self.myState.isOpen)
    self.myState.quantizer = myQuantizerValue;

现在,XCode 将不接受使用 '.' 进行访问。操作员。它说“表达式不可分配”。我尝试将 myState 更改为指针并将我的读/写转换为用户 '->' 运算符,例如:

self.myState->isOpen = TRUE;

然后它会在分配上给出运行时错误。我应该怎么做才能以简单的方式访问和修改这些属性?我想使用结构构造函数只是为了避免为 MyStruct 中的每个属性声明和合成单独的变量。

【问题讨论】:

@matt 我使用 TRUE 和 FALSE 而不是 YES 和 NO。它们在编译器眼中不一样吗?而且我不明白合成具有我定义的结构类型的变量有什么问题?我拥有的所有其他变量(包括简单的非原子变量、赋值 BOOL)都是在我的 .m 文件的开头合成的。我想我会像他们一样合成 myState 变量(MyState 类型)。有问题吗? 【参考方案1】:

这与您不能分配给视图的frame 属性的size 的原因相同。这是Objective-C的限制。请参阅this section of my book 末尾对此问题的讨论。正如我在那里解释的那样,您必须将结构属性值获取到变量中,更改结构的成员,然后重新分配给属性:

struct MyState s = self.myState;
s.isOpen = YES;
self.myState = s;

基本上这是因为self.myState 中的“点”与myState.isOpen 中的“点”完全不同。第一个是对myState 方法 的Objective-C 调用,并返回一个结构。第二个是对结构成员的 C 访问。

另一种选择是一开始就不使用Objective-C属性:直接访问实例变量:

self->myState.isOpen = YES;

但是如果不公开这个实例变量,你当然不能从其他类中做到这一点......

【讨论】:

感谢您的明确答复。我无法理解其他示例。就我而言,我在 for 循环的每次迭代中更新结构。在那里进行双重分配似乎相当开销:/无论如何,谢谢它的工作原理! 如果我在 .m 文件的全局范围内声明 s 怎么办?我可以直接使用、编辑和访问它(并使用 s 作为我的状态保持者)吗?这似乎直接达到了我想要的效果,比 fetch&write 好多了。 如果您关心效率,请不要使用 Objective-C 属性。直接访问实例变量即可:self->myState.isOpen = YES; 现在你说的是纯 C。 不,这是 C 的限制,而不是 Objective-C 的限制。它与 Objective-C'c 点表示法无关。我在书中解释了这一点。 @batilc self->myState.isOpen = YES 一个有效的声明。 self 总是可以直接访问 self 的实例变量。这解决了获取和替换问题:您现在直接分配给结构的成员。我在回答中要指出的是,一个对象通常无法看到 不同 对象的实例变量。默认情况下,它们是私有的(实际上是受保护的)。 Objective-C 属性的全部意义在于它们可以帮助您将公共访问器方法放在私有实例变量之前。【参考方案2】:

我不认为你可以做你想做的事。您不能使结构成为属性并将值分配给结构的元素之一。相反,您必须设置一个包含相同结构的局部变量,对其进行配置,然后将整个结构分配给该属性:

MyState aStruct;

aStruct.isOpen = TRUE;
aStruct.quantizer = myQuantizerValue;

self.myState = aStruct;

请注意,出于同样的原因,您在视图的 frame 和 bounds 属性方面也存在同样的问题。

CGRect 是一个结构。该视图有一个 bounds CGRect 属性。

你不能说

myView.bounds.origin.x = 70;

相反,你不得不说;

CGRect bounds = myView.bounds;
bounds.origin.x = 70;

myView.bounds = bounds;

编辑:废话,看起来马特和我给出了大致相同的答案,但他在发送按钮上更快。

【讨论】:

感谢您的帮助!对事情进行多次确认总是好的。【参考方案3】:

由于 self.myState 中的“点”是目标 C 而 myState.isOpen 中的“点”是“C”成员结构,因此要像您想要的那样直接访问该结构,请改用下划线。 _myState.isOpen = TRUE;

【讨论】:

以上是关于Objective-C 结构定义和修改给出错误“表达式不可分配”?的主要内容,如果未能解决你的问题,请参考以下文章

15.表结构修改-修改表定义和表名

sql server 2005代码错误 提示插入错误: 列名或所提供值的数目与表定义不匹配。

用户定义的结构在声明时无法识别并给出类型错误

请根据给出的数据库表的结构和要求,写出相应的Sql语句。

请根据给出的数据库表的结构和要求,写出相应的Sql语句。

请根据给出的数据库表的结构和要求,写出相应的Sql语句