实现有序字典

实现字典有序化的方法

  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)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)aKey atIndex:(NSUInteger)index;
//插入键值对至给定index
- (void)removeLastObject;
//移除最后一个键值对
- (void)removeObjectAtIndex:(NSUInteger)index;
//移除给定index的键值对
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
//插入键值对至给定indexes
- (void)insertObjects:(NSArray *)objects keys:(NSArray> *)keys atIndexes:(NSIndexSet *)indexes;
//移除给定indexes的键值对
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
//替换给定indexes的值
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects;
NS_ASSUME_NONNULL_END
@end

本文最后附上demo地址:OrderedMutableDictionary

你可能感兴趣的:(实现有序字典)