为什么NSOrderedSet不从NSSet继承?

jha*_*ott 50 objective-c nsset ios nsorderedset

当然,有序集是一个集合的更具体的情况,那么为什么NSOrderedSet继承NSObject而不是NSSet

Tom*_*ing 76

我经历了界面NSSet并且你是对的,有序集似乎满足Liskov替换原则并且可以继承NSSet.

有一种方法可以解决这个问题:mutableCopy.返回值mutableCopy必须是a NSMutableSet,但NSMutableOrderedSet应该继承NSOrderedSet.你不能两者兼得.

让我解释一些代码.首先,让我们来看看正确的行为NSSetNSMutableSet:

NSSet* immutable = [NSSet set];
NSMutableSet* mutable = [immutable mutableCopy];

[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
Run Code Online (Sandbox Code Playgroud)

现在,让我们假装NSOrderedSet继承自NSSetNSMutableOrderedSet继承自NSOrderedSet:

//Example 1
NSOrderedSet* immutable = [NSOrderedSet orderedSet];
NSMutableOrderedSet* mutable = [immutable mutableCopy];

[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // NO (this is the problem)
Run Code Online (Sandbox Code Playgroud)

如果NSMutableOrderedSet继承而来NSMutableSet呢?然后我们得到一个不同的问题:

//Example 2
NSOrderedSet* immutable = [NSOrderedSet orderedSet];
NSMutableOrderedSet* mutable = [immutable mutableCopy];

[mutable isKindOfClass:[NSSet class]]; // YES
[mutable isKindOfClass:[NSMutableSet class]]; // YES
[mutable isKindOfClass:[NSOrderedSet class]]; // NO (this is a problem)
Run Code Online (Sandbox Code Playgroud)

在示例1中,您将无法将NSOrderedSet一个函数传递给期望的函数,NSSet因为行为是不同的.基本上,这是一个向后兼容性问题.

在示例2中,您不能将NSMutableOrderedSet一个函数传递给期望的函数,NSOrderedSet因为前者不会从后者继承.

所有这一切都是因为NSMutableOrderedSet不能从两者继承NSMutableSet,NSOrderedSet因为Objective-C没有多重继承.解决这个问题的方法是为NSMutableSet和制作协议NSOrderedSet,因为这样NSMutableOrderedSet就可以实现这两种协议.我猜Apple开发人员只是在没有额外协议的情况下更简单.

  • 很好的答案,这是在NSHipster书中使用的,这是我如何找到这个问题...你知道为什么NSHipster书直接将这个问题链接到NSSet是一个类集群吗?我根本不知道如果NSSet是一个如何具体类,这与可变复制问题有什么不同,你知道吗?http://nshipster.com/nsorderedset/ (2认同)