4

我有一个 CGSize 的属性:

@property (nonatomic) CGSize descriptionSize;

'

@synthesize descriptionSize = _descriptionSize;

我可以通过点语法访问高度:

self.descriptionSize.height = 35;

但这如何与括号语法一起使用?

[self setDescriptionSize:???];

对我来说看起来很愚蠢,但我无法得到线索。提前致谢!

4

3 回答 3

6

这是属性点符号的缺陷之一:self.descriptionSize.height 中的这两个点看起来相同,但含义却截然不同。第一个是映射到“get descriptionSize”方法的属性访问器,但第二个是老式结构引用。第一个点返回一个 CGSize标量,而不是指向对象中大小值的指针。当第二个点在返回的 CGSize 中设置高度时,它是在堆栈上设置一个值,而不是更改对象中的值。这就是你必须这样做的方式:

CGSize size = self.descriptionSize;
size.height = 35;
self.descriptionSize = size;

…或没有属性点符号的等价物:

CGSize size = [self descriptionSize];
size.height = 35; // we still use the dot here: size is a struct not an object
[self setDescriptionSize:size];
于 2012-05-04T06:45:28.217 回答
5

的实现descriptionSize将返回结构的副本CGSize因此您不能直接使用它并希望它能够工作。您需要做的是获取整个CGSize结构,对其进行修改,然后将其传回:

CGSize size = [self descriptionSize];
size.height = 35;
[self setDescriptionSize:size];

但是,鉴于您正在处理的属性self并且该属性不是object,这需要内存管理,修改大小的最有效方法是:

_descriptionSize.height = 35;

但是,如果:

  1. 对象不是self
  2. 您已经手动编写了 setter 方法来做一些改变大小的副作用(例如,为了自动更新视图而使视图的位无效)。
于 2012-05-04T06:38:47.470 回答
2

点语法有两种不同的含义:一个结构引用(CGSize 是一个 C 结构),或者一个 Objective-C 消息发送。

理论上,如果你有一个类似的方法- (void)doSomething;,你可以这样调用它myObject.doSomething; //bad style:不要这样做。除了获取或设置值之外,点语法不适用于调用实际执行操作的方法(尽管语言或 IDE 中没有任何内容会阻止您)。

合成属性会创建访问器方法:- (myType)myProperty- (void)setMyProperty:(myType)newValue. 在这里,点语法允许您以普通方式访问 getter(因为 getter 是一个普通的 Objective-C 方法),并且对于 setter 有一个特殊情况:myObject.myProperty = newValue被翻译为[myObject setMyProperty:newValue].

这意味着您可以在点语法和 Objective-C 样式的属性消息发送语法之间切换(以及技术上所有其他无参数的 Objective-C 方法发送),但您必须使用点语法来访问结构成员。结构不是对象,它们现在知道方法。

于 2012-05-04T07:02:09.500 回答