在Objective-C中,在类别中声明只读属性有意义吗?

在Objective-C中,在类别中声明只读属性有意义吗?,objective-c,Objective C,假设我有Tree.h和Tree+Extensions.h。我知道,如果我在Tree+Extensions.ha@property(nonatomic)NSString*color中声明并访问它,它将崩溃,并且我可以使用objc\u getassociated object和objc\u setassociated object获得类似的功能 然而,我也看到了这一点: // Tree+Extensions.h @interface Tree (Extensions) @property (nona

假设我有
Tree.h
Tree+Extensions.h
。我知道,如果我在
Tree+Extensions.h
a
@property(nonatomic)NSString*color
中声明并访问它,它将崩溃,并且我可以使用
objc\u getassociated object
objc\u setassociated object
获得类似的功能

然而,我也看到了这一点:

// Tree+Extensions.h
@interface Tree (Extensions)
@property (nonatomic, readonly) NSString *color;
@end

// Tree+Extensions.m
@implementation Tree (Extensions)
- (NSString *)color {
    return @"green";
}
@end
请注意,类别中的属性声明为
只读
,并且访问器方法返回可以计算的内容


我看到这段代码在工作,但想知道为什么这比在头文件中声明访问器方法更可取。

使用您编写的代码,即使在类中,您也不能调用
setColor:
,当您想要返回未由ivar支持的内容(例如计算)时,这是有意义的你不想暴露在外面的世界里


回答:这是首选,因为您不需要从类外访问此属性。

我们先不考虑这是一个类别的事实,只讨论以下内容:

@interface Tree
@property (nonatomic, readonly) NSString *color;
@end
@implementation Tree
- (NSString *)color {
    return @"green";
}
@end
据我所知,你的问题是:这和这有什么区别:

@interface Tree
- (NSString *)color;
@end
@implementation Tree
- (NSString *)color {
    return @"green";
}
@end
从完全实际的角度来看,没有区别。人们确实习惯于声明属性,但事实上,这两种声明具有完全相同的效果——即,在任何一种情况下,调用方(导入接口的任何人)都可以毫无差别地说
[aTree color]
aTree.color
。属性用法(
aTree.color
)是方法调用
[aTree color]
,反之亦然。调用方可以说
aTree.color
,即使只声明了
color
方法(不是属性)。例如,这就是为什么说
myArray.count
是合法的(也是常见的),即使NSArray的
count
没有声明为属性(它只是一个方法)。反之亦然,说
[myViewController navigationController]
是合法的(也是常见的),即使
navigationController
被声明为属性

现在,在大多数情况下,声明属性的原因是为了让编译器合成相应的实例变量和相应的方法实现。但在这种情况下,这一切都没有发生;没有实例变量,也没有要合成的getter(它是显式编写的)

最后,让我们回到原来的问题并总结一下:不能使用命名类别(如
树(扩展)
)向现有类添加实例变量。作为:

在类别接口中包含属性声明是有效的语法,但在类别中不可能声明额外的实例变量。这意味着编译器不会合成任何实例变量,也不会合成任何属性访问器方法


在本例中,您没有向现有类添加实例变量,也没有尝试合成“getter”:
readonly
属性声明由现有的“getter”方法支持,正如您正确地说的,该方法计算整个cloth的结果。因此,属性声明虽然有点毫无意义,但却是完全合法和有效的:它只声明了“getter”方法。

对于属性,您可以使用
操作符访问它们,对于无法访问的方法。@holex不正确。试试看@你可以,但你不应该t@ScottBerrevoets,我同意你的看法,我确实用错了上面的词。@matt:Apple的示例代码并不总是最好的,但在这种情况下,它并不重要。苹果确实在这里提到了一些关于财产的惯例:不管是谁投了反对票,这显然是对事实的无知。他们可能甚至没有读过你的答案。无论如何,这里的问题是主观的,因为它基本上是在问为什么在两种语法都一样好的情况下,某个语法应该用在另一个语法上。好吧,@Nighthawk441,我想有些人确实认为你不能说
someObject.someProperty
,除非
someProperty
是一个明确声明的属性。我想我以前是这么想的!但这不是真的,从来都不是;如果
someProperty
是一个声明为不带参数并返回非类结果的方法的名称,则它可以工作。这两个声明之间(显然)存在差异:一个声明属性,另一个声明方法。这本身就是一个区别。但结果也有区别:可以在运行时查询属性并返回内省信息。这个方法不行。@NikolaiRuhe我看不出来。一个对象对于它的方法和它的属性都是可以内省的,如果你喜欢的话。