我想以抽象的方式做以下事情:
// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end
// .m
@interface SomeObject ()
@property (readwrite) NSMutableArray myProperty;
@end
@implementation SomeObject
@end
根据Subclassing with Properties in the Mac Developer Library部分,允许使用readonly
覆盖readwrite
个属性。什么不起作用是使用属性类型的子类。 我使用NSMutableArray作为示例,但它可以是任何其他类/子类组合。
根据继承规则,它应该没问题。 readonly
只生成getter,也允许返回子类对象。
当您需要某些属性的子类类型供内部使用时,如何处理此类情况?
一种丑陋的方式如下,但我想避免这种情况,因为这意味着在访问子类方法时我不能使用self.
getter和setter。
// .h
@interface SomeObject : NSObject
@property (readonly) NSArray myProperty;
@end
// .m
@implementation SomeObject {
NSMutableArray _myProperty;
}
@synthesize myProperty = _myProperty;
@end
答案 0 :(得分:4)
编辑(根据您的修改):编辑后的具体情况是一种特殊且常见的情况(如果它们可以同时进行),需要仔细考虑。< / p>
这是一个特殊的原因是因为子类是暴露类的可变形式。调用者可能会在收到后不会更改。但是如果你交回你的内部对象,那么它可能会发生变异。您有几种选择:
返回不可变副本。这通常是小型馆藏的最佳解决方案。这当然是最简单的。但是如果可能经常调用访问器并且集合很大,那么它可能会非常昂贵。
使您的内部属性不可变。如果对属性的请求比对属性的更改更常见,则在对象变异时(使用arrayByAddingObject:
,subarrayWithRange:
等)重新创建对象会更有效。
警告调用者返回的对象可能会改变.... uggh ...我在一个需要性能的情况下完成了这个,但这很危险。
我从来没有这样做过,但你也可以这样创建自己的copy-on-write:直接返回可变版本并标记一个现在“脏”的标志。当内部需要变异时,制作一个可变副本并将其存储在您的属性中(放弃旧的集合)。这似乎有很多复杂性,但在某些情况下可能会有用,特别是如果读取和写入倾向于分开聚集(大量读取后跟大量写入)。
OLD ANSWER:
我认为你的目标是让myProperty
成为一种不透明的类型,而不是泄漏它是NSString
的事实?或许这样你以后可以改变主意实际实现的方式?有几个选择。最简单的方法是定义类型id
。然后在内部将其视为字符串。 id
可以是任何东西。它通常优先于NSObject*
。
如果您想在内部获得更多类型安全性,那么您可以使用另一个类型为NSString
的名称创建一个私有属性,并将其返回myProperty
,如下所示:
@interface SomeObject : NSObject
@property (readonly) id myProperty;
@end
@interface SomeObject ()
@property (readwrite) NSString *myInternalProperty;
@end
@implementation SomeObject
- (id)myProperty {
return myInternalProperty;
}
@end
您可以使用的另一种隐藏技术(如果隐藏对您来说非常重要)是一个子类。例如:
@class MyOpaque;
@interface SomeObject : NSObject
@property (readonly) MyOpaque *myProperty;
@end
@interface MyOpaque : NSString
@end
@implementation MyOpaque
@end
@implementation SomeObject
@end
由于调用者没有@interface
的{{1}}定义,因此如果没有编译器警告,他就无法向其发送消息。
答案 1 :(得分:-7)
当您需要某些子类类型时,如何处理此类情况? 内部使用的财产?
属性明确不适用于内部使用,它们是公共接口的成员。
如果您需要内部值,请定义成员字段并覆盖属性的setter以设置内部值。