美文网首页
实现有序字典

实现有序字典

作者: Locke | 来源:发表于2017-03-20 16:53 被阅读473次

    实现字典有序化的方法

    1. 分类添加数组变量存储key值;
    2. 按照NSDictionarykey来进行排序;
    3. 将字典中的value再放到一个字典里面key分别有使用有序的字符串;
    4. 先将字典转模型,再放到数组里面;
    这里只说一下使用“分类添加数组变量存储 key 值“的方式实现字典的有序化

    Objective-C中可以通过Category给一个现有的类添加属性,但是不能添加实例变量。但是我们可以通过 Associated Objects 来解决这个问题,给NSMutableDictionary添加一个NSMutableArray的变量,来保存添加的key-value(键值对)key值。之后再通过Method Swizzling来进行key值的保存过程。

    Associated Objects 相关的函数
    OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
        OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
    OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
        OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
    OBJC_EXPORT void objc_removeAssociatedObjects(id object)
        OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
    

    *objc_setAssociatedObject用于给对象添加关联对象,传入nil则可以移除已关联的对象;
    *objc_getAssociatedObject用于获取关联对象;
    *objc_removeAssociatedObjects用于移除一个对象的所有的关联对象
    具体的信息请移步博文 Objective-C Associated Objects 的实现原理

    上代码

    static const void *OrderedDictionaryKeys = (void *)@"OrderedDictionaryKeys";
    -(NSMutableArray *)keys {
        return objc_getAssociatedObject(self, OrderedDictionaryKeys);
    }
    - (void)setKeys:(NSMutableArray *)keys {
        objc_setAssociatedObject(self, OrderedDictionaryKeys, keys, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    Method Swizzling

    Method Swizzling本质上就是对IMPSEL进行交换。
    具体了解请移步博文 iOS黑魔法-Method Swizzling

    上代码

    @implementation NSObject (Swizzling)
    - (void)swizzlingMethod:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
        Class class = [self class];
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (didAddMethod) {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
    @end
    
    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            @autoreleasepool {
                [objc_getClass("__NSDictionaryM") swizzlingMethod:@selector(setObject:forKey:) swizzledSelector:@selector(swizzled_setObject:forKey:)];
            }
        });
    }
    - (void)swizzled_setObject:(nonnull id)anObject forKey:(nonnull id<NSCopying>)aKey{
        [self.keys addObject:aKey];
        [self swizzled_setObject:anObject forKey:aKey];
    }
    

    #######OrderedMutableDictionary主要实现的方法

    @interface NSMutableDictionary (Ordered)
    NS_ASSUME_NONNULL_BEGIN
    @property (nonatomic, strong, readonly, nullable) NSMutableArray *keys;
    //获取给定index的对象
    - (id)objectAtIndex:(NSUInteger)index;
    //插入键值对至给定index
    - (void)insertObject:(id)anObject forKey:(id<NSCopying>)aKey atIndex:(NSUInteger)index;
    //插入键值对至给定index
    - (void)removeLastObject;
    //移除最后一个键值对
    - (void)removeObjectAtIndex:(NSUInteger)index;
    //移除给定index的键值对
    - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
    //插入键值对至给定indexes
    - (void)insertObjects:(NSArray<id> *)objects keys:(NSArray<id <NSCopying>> *)keys atIndexes:(NSIndexSet *)indexes;
    //移除给定indexes的键值对
    - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
    //替换给定indexes的值
    - (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray<id> *)objects;
    NS_ASSUME_NONNULL_END
    @end
    

    本文最后附上demo地址:OrderedMutableDictionary

    相关文章

      网友评论

          本文标题:实现有序字典

          本文链接:https://www.haomeiwen.com/subject/fldbwttx.html