ios - NSMutableSet 与自定义 isEqual : and hash callbacks

标签 ios parse-platform core-foundation foundation nsmutableset

我正在尝试创建一个自定义 NSMutableSet,它不使用对象上的标准 isEqual:hash 选择器。

通常我想将其与 Parse 一起使用。我有一个包含 PFObject 子类实例的 NSMutableSet,如果它们具有相同的 objectId,我认为它们相等。 我知道我可以在 PFObject 子类中重写 isEqual:hash,但我不希望在我的所有对象上使用该功能。此外,Parse 在内部使用这些方法,所以我不想搞乱它们。

这是我到目前为止所想到的:

#import <Foundation/Foundation.h>

@interface NSMutableSet (Additions)

+ (NSMutableSet *)setWithParseObjectIdIsEqualCallback;

@end

 

#import "NSMutableSet+Additions.h"

@implementation NSMutableSet (Additions)

static Boolean ParseObjectIdIsEqualCallback(const void *value1, const void *value2)
{
    PFObject *obj1 = (__bridge id)value1;
    PFObject *obj2 = (__bridge id)value2;
    NSCParameterAssert([obj1 isKindOfClass:PFObject.class]);
    NSCParameterAssert([obj2 isKindOfClass:PFObject.class]);
    NSCParameterAssert([obj1 isMemberOfClass:obj2.class]);

    return [obj1.objectId isEqualToString:obj2.objectId];
}

static CFHashCode ParseObjectIdHashCallback(const void *value)
{
    PFObject *object = (__bridge id)value;
    NSCParameterAssert([object isKindOfClass:PFObject.class]);

    return object.objectId.hash;
}

+ (NSMutableSet *)setWithParseObjectIdIsEqualCallback
{
    CFSetCallBacks callbacks = kCFTypeSetCallBacks;
    callbacks.equal = ParseObjectIdIsEqualCallback;
    callbacks.hash  = ParseObjectIdHashCallback;
    CFMutableSetRef set = CFSetCreateMutable(kCFAllocatorDefault, 0, &callbacks);
    return CFBridgingRelease(set);
}

@end

我真的不知道它是否有效或者使用是否安全,而且我对 Core Foundation 对象和函数(如 CFBridgingRelease())非常不熟悉。

最佳答案

我认为您的方法不必要地复杂:您可以在 wrapper 类中提供自己的 isEqual:hash 实现,并包装您的在放入 NSMutableSet 之前先将 PFObject 放入其中:

@interface PFObjectWrap {
    PFObject *_obj;
}
-(BOOL)isEqual:(id)other;
-(NSUInteger)hash;
+(PFObject*)wrapped;
-(id)initWithPFObject:(PFObject*)obj;
+(PFObjectWrap)wrap:(PFObject*)obj;
@end

@implementation PFObjectWrap
-(id)initWithPFObject:(PFObject*)obj {
    if (self = [super init]) {
        _obj = obj;
    }
    return self;
}
+(PFObjectWrap)wrap:(PFObject*)obj {
    return [[PFObjectWrap alloc] initWithPFObject:obj];
}
+(PFObject*)wrapped {
    return _obj;
}
-(BOOL)isEqual:(id)other {
   // Put your custom implementation here
}
-(NSUInteger)hash {
   // Put your custom implementation here
}
@end

现在,您可以在添加到 NSMutableSet 之前将对象包装到 PFObjectWrap 中:

NSMutableSet *set = [NSMutableSet set];
[set addObject:[PFObjectWrap wrap:myObject1]];
[set addObject:[PFObjectWrap wrap:myObject2]];

当然你还需要在搜索NSMutableSet之前换行。

关于ios - NSMutableSet 与自定义 isEqual : and hash callbacks,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26785979/

相关文章:

ios - Cocos2d:在运行时为Sprite节点中批处理的CCSprite设置zOrder似乎无效

ios - 是否可以在 Swift 的 UITableViewCell 中添加 UITableView

ios - 托管解析是否支持推送通知?

android - 查询解析数据库,通过忽略大小写匹配关键字返回

ios - 无法初始化 PFObject 子类

iOS 崩溃核心位置 CFBasicHashCreateCopy?

iphone - 确定使用 NSString draw/size 方法绘制什么子字符串

c - 如何从带有 carbon 的插件内部获取包引用?

将默认数据库路径更改为组路径后,iOS RealmSwift 不会更新模型

ios - 你如何在 firebase 数据库的文件夹中创建一个文件夹?