类扩展中的“属性具有先前的声明”错误:错误或功能?

时间:2018-10-31 13:03:10

标签: objective-c clang xcode10

在Objective-C中,您可以通常在这样的类扩展中将readonly属性重新声明为readwrite

@interface PubliclyImmutablePrivatelyMutableClass : NSObject

@property (readonly, nonatomic) SomeStateEnum someState;

@end

// In "PubliclyImmutablePrivatelyMutableClass+Private.h"
// or "PubliclyImmutablePrivatelyMutableClass.m"
@interface PubliclyImmutablePrivatelyMutableClass()

@property (readwrite, nonatomic) SomeStateEnum someState;

@end

// In "PubliclyImmutablePrivatelyMutableClass.m"
@implementation PubliclyImmutablePrivatelyMutableClass @end

但是,如果我在类扩展名中将属性引入为readonly,并尝试在第二个扩展名中将其重新声明为readwrite,则Xcode 10的Clang会给我一个编译器错误:

@interface ClassWithPrivateImmutableInternallyMutableProperty : NSObject

// any public API

@end


// In "ClassWithPrivateImmutableInternallyMutableProperty+Private.h"
@interface ClassWithPrivateImmutableInternallyMutableProperty()

@property (readonly, nonatomic) SomePrivateStateEnum somePrivateState;

@end


// In "ClassWithPrivateImmutableInternallyMutableProperty.m"
@interface ClassWithPrivateImmutableInternallyMutableProperty()

@property (readwrite, nonatomic) SomePrivateStateEnum somePrivateState; // error: property has a previous declaration

@end

@implementation ClassWithPrivateImmutableInternallyMutableProperty
// other API
@end

现在我想知道:

  • 编译器错误是Clang中的错误/回归还是故意的功能?
  • 如果是bug,除了手动执行设置器之外,还有其他解决方法吗?

1 个答案:

答案 0 :(得分:0)

我相信这是编译器的正确行为。

在第二个示例中,您使用两个具有相同名称()的类延续类来两次声明相同的属性。它实际上与在同一扩展名中两次声明相同的属性名称相同。

请注意,这与第一个示例不同,在第一个示例中,该属性首先在 header 中声明,然后在名为()的单个类延续类别中重新声明。

如果我是对的,那么答案是用“ (Private)”而不是“ ()”来标记“ + private”类扩展名:

@interface ClassWithPrivateImmutableInternallyMutableProperty(Private)

如果您有私有扩展的任何实现,那么

@implementation ClassWithPrivateImmutableInternallyMutableProperty(Private)

希望对您有帮助!