Objective c &引用;财产有一个以前的声明;类扩展中的错误:错误还是功能?

Objective c &引用;财产有一个以前的声明;类扩展中的错误:错误还是功能?,objective-c,clang,xcode10,Objective C,Clang,Xcode10,在Objective-C中,您通常可以在类扩展中将readonly属性重新声明为readwrite,如下所示: @interface PubliclyImmutablePrivatelyMutableClass : NSObject @property (readonly, nonatomic) SomeStateEnum someState; @end // In "PubliclyImmutablePrivatelyMutableClass+Private.h" // or "Publ

在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的叮当声会给我一个编译器错误:

@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
现在我想知道:

  • 编译器错误是叮当作响的bug/回归还是故意的特性
  • 如果它是一个bug,除了手动实现setter,还有其他解决方法吗

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

      在第二个示例中,您使用两个同名的类延续类别
      ()
      ,在两种情况下声明相同的属性。它实际上与在同一扩展中两次声明相同的属性名相同

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

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

      此外,如果您有专用扩展的任何实现:

      @implementation ClassWithPrivateImmutableInternallyMutableProperty(Private)
      

      我希望这有帮助

      如果你把一个名字放在括号里,它就不再是一个类的延续了:它变成了一个普通的旧类别,而且它们的行为与类的延续不同(例如,没有自动合成属性,没有添加实例变量的方法)。如果要使用两个类延续,则不能在这两个类中声明名称相同的属性。可能在实现中使用内部名称,如
      \u somePrivateState
      ,然后在+私有类继续中提供一个getter,该getter公开支持属性
      -(SomePrivateEnum)somePrivateState
      @implementation ClassWithPrivateImmutableInternallyMutableProperty(Private)