在我的 macOS Objective-C 应用程序中,我创建了 NSMutableSet 的子类。我想要实现的是一个不使用 isEqual: 作为比较策略的 NSMutableSet。具体来说,该集合将包含 NSRunningApplication 类型的对象,并且我希望该集合基于对象捆绑标识符的相等性工作。以下是我的实现:
头文件:
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface BundleIdentifierAwareMutableSet : NSMutableSet
@property (atomic, strong) NSMutableSet *backStorageMutableSet;
@property (atomic, strong) NSMutableArray *backStorageMutableArray;
@end
NS_ASSUME_NONNULL_END
实现文件:
#import "BundleIdentifierAwareMutableSet.h"
@implementation BundleIdentifierAwareMutableSet
@synthesize backStorageMutableSet;
- (instancetype)init {
self = [super init];
if (self) {
self.backStorageMutableSet = [[NSMutableSet alloc] init];
self.backStorageMutableArray = [[NSMutableArray alloc] init];
}
return self;
}
- (NSUInteger)count {
return [self.backStorageMutableArray count];
}
- (NSRunningApplication *)member:(NSRunningApplication *)object {
__block NSRunningApplication *returnValue = nil;
[self.backStorageMutableArray enumerateObjectsUsingBlock:^(NSRunningApplication * _Nonnull app, NSUInteger __unused idx, BOOL * _Nonnull stop) {
if ([app.bundleIdentifier isEqualToString:[object bundleIdentifier]]) {
returnValue = app;
if (![app isEqual:object]) {
NSLog(@"An ordinary set would have not considered the two objects equal.");
}
*stop = YES;
}
}];
return returnValue;
}
- (NSEnumerator *)objectEnumerator {
self.backStorageMutableSet = [NSMutableSet setWithArray:self.backStorageMutableArray];
return [self.backStorageMutableSet objectEnumerator];
}
- (void)addObject:(NSRunningApplication *)object {
NSRunningApplication *app = [self member:object];
if (app == nil) {
[self.backStorageMutableArray addObject:object];
}
}
- (void)removeObject:(NSRunningApplication *)object {
NSArray *snapShot = [self.backStorageMutableArray copy];
[snapShot enumerateObjectsUsingBlock:^(NSRunningApplication * _Nonnull currentApp, NSUInteger __unused idx, BOOL * _Nonnull __unused stop) {
if ([[currentApp bundleIdentifier] isEqualToString:[object bundleIdentifier]]) {
[self.backStorageMutableArray removeObject:currentApp];
if (![currentApp isEqual:object]) {
NSLog(@"An ordinary set would have not considered the two objects equal.");
}
}
}];
}
这似乎有效,实际上,当适用时,Xcode 记录普通 NSMutableSet 不会认为两个成员相等。我想把这个实现带到生产应用程序中,但恐怕我没有考虑重要的事情,因为这是我第一次继承 NSMutableSet。例如,我担心以下方法:
- (NSEnumerator *)objectEnumerator {
self.backStorageMutableSet = [NSMutableSet setWithArray:self.backStorageMutableArray];
return [self.backStorageMutableSet objectEnumerator];
}
这是我对 backStorageMutableSet 的唯一使用,因为其余的都支持到数组中。这很好还是会带来麻烦?子类的其他部分会不会带来问题?任何帮助将不胜感激。谢谢