43

在 XCode 5.1 中,会出现一个新警告。这让我明白——显然——我做错了什么。

这个想法是有一个对象(一个模型),它是从原始类继承的可变版本。所以这个想法是打开一个readonly属性readwrite

@interface Car : NSObject
    @property (strong, readonly) NSString *name;
@end

@interface MutableCar : Car
    @property (strong, readwrite) NSString *name;
@end

这些需要在单独的文件中(如两个普通类)。

它给出了这个警告:

Auto property synthesis will not synthesize property 'name' because it is 'readwrite' but it will be synthesized 'readonly' via another property

所以我想知道做类似事情的正确解决方案是什么,如果可能的话。如果需要编写访问器并避免使用自动合成等。请准确并用文档或其他内容支持您的答案。

4

1 回答 1

60

我建议在您的 MutableCar 实现中显式合成该属性。如:

@implementation MutableCar

@synthesize name;

@end

这样clang就不会尝试使用自动合成

编辑:

如果您不想使用封装并且出于其他原因需要从父类访问 ivar,那么您需要做更多的努力:

首先 Car .h 文件保持不变(我添加了一个 printVar 方法来打印 ivar 和属性):

@interface Car : NSObject

- (void)printVar;

@property (strong, readonly) NSString *name;

@end

现在在 .m 文件上,我正在实现 printVar 方法并添加一个类扩展来告诉 clang 创建 setter:

// Private class extension, causes setName: to be created but not exposed.
@interface Car ()

@property (strong, readwrite) NSString *name;

@end

@implementation Car

- (void)printVar
{
    NSLog(@"<Car> Hello %@, ivar: %@", self.name, _name);
}

@end

现在您可以像以前一样创建 MutableCar.h:

@interface MutableCar : Car

@property (strong, readwrite) NSString *name;

@end

你的 MutableCar.m 应该是这样的:

@implementation MutableCar

@dynamic name;

- (void)printVar
{
    [super printVar];
    NSLog(@"<MutableCar> Hello %@", self.name);
}

@end

这样,父级上的 _name ivar 实际上是使用父级设置器编写的,您可以访问它。

于 2014-03-13T17:44:46.003 回答