我想知道实现可变与不可变数据结构的正确模式是什么。我理解这个概念以及它是如何工作的,但是如果使用底层的 Cocoa 数据结构,我应该如何实现呢?NSSet
我的意思是,例如,如果我使用 a 。可以说我有以下内容:
// MyDataStructure.h
@interface MyDataStructure : NSObject
@property (nonatomic, strong, readonly) NSSet * mySet;
@end
// MyDataStructure.m
@interface MyDataStructure ()
@property (nonatomic, strong) NSMutableSet * myMutableSet;
@end
@implementation MyDataStructure
- (NSSet *)mySet
{
return [_myMutableSet copy];
}
@end
我使用可变集作为底层数据结构的唯一原因是,此类的可变版本可以篡改它。MyDataStructure
本身并不真的需要一个可变集。因此,假设我已经实现了一些初始化程序以使此类有用,MyMutableDataStructure
如下所示:
// MyDataStructure.h (same .h as before)
@interface MyMutableDataStructure : MyDataStructure
- (void)addObject:(id)object;
@end
// MyDataStructure.m (same .m as before)
@implementation MyMutableDataStructure
- (void)addObject:(id)object
{
[self.myMutableSet addObject:object];
}
@end
通过使用这种模式,底层数据结构总是可变的,它的不可变版本只是一个不可变的副本(或者是吗??)。
NSCopying
这也引出了实现协议时出现的另一个问题。这是一个示例实现:
- (id)copyWithZone:(NSZone *)zone
{
MyDataStructure * copy = [MyDataStructure allocWithZone:zone];
copy->_myMutableSet = [_myMutableSet copyWithZone:zone];
return copy;
}
copyWithZone:
如果适用,不返回不可变副本?所以我基本上将 a 分配NSSet
给一个NSMutableSet
属性,不是吗?
编辑:在深入研究这个问题时,我发现了围绕这个问题的更多问题。
mySet
应该copy
代替strong
.- 我的
copyWithZone:
实现也不对。我在第一篇文章中没有提到它,但该实现与数据结构 (MyDataStructure
) 的不可变版本有关。正如我所读到的,不可变数据结构实际上并没有创建副本,它们只是返回自己。这就说得通了。 - 由于 2.,我需要
copyWithZone:
在可变版本 (MyMutableDataStructure
) 中覆盖。
为了清楚起见:
// MyDataStructure.h
@property (nonatomic, copy, readonly) NSSet * mySet;
和
// MyDataStructure.m
@implementation MyDataStructure
- (id)copyWithZone:(NSZone *)zone
{
// We don't really need a copy, it's Immutable
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// I also implement -mutableCopyWithZone:, in which case an actual (mutable) copy is returned
MyDataStructure * copy = [MyMutableDataStructure allocWithZone:zone];
copy-> _myMutableSet = [_myMutableSet mutableCopyWithZone:zone];
return copy;
}
@end
@implementation MyMutableDataStructure
- (id)copyWithZone:(NSZone *)zone
{
return [self mutableCopyWithZone:zone];
}
@end
起初这似乎很棘手,但我想我已经掌握了窍门。所以剩下的问题是:
- 模式是否正确?
- getter 是否
mySet
返回可变或不可变实例? copy
(之前未列出)使用copy
property 属性时我真的需要信号吗?
感谢您耐心读到这里。最好的。