这段代码是如何创建NSMutableArray的备份的?

时间:2013-03-26 11:42:02

标签: iphone ios objective-c categories

请查看以下类别...据我所知,无法将实例变量添加到类别中..

·H

//
// Created by macbook on 17.01.13.
//
// To change the template use AppCode | Preferences | File Templates.
//


#import <Foundation/Foundation.h>

@interface NSMutableArray (Cache)
@property (nonatomic, strong) NSArray *backup;

- (void)restoreBackup;
@end

的.m

//
// Created by macbook on 17.01.13.
//
// To change the template use AppCode | Preferences | File Templates.
//
#import "NSMutableArray+Cache.h"
#import <objc/runtime.h>
#define CEBackupKey @"Backup"
@implementation NSMutableArray (Cache)
#pragma mark - Properties
- (NSArray *)backup {
    return objc_getAssociatedObject(self, CEBackupKey);
}
- (void)setBackup:(NSArray *)backup {
    objc_setAssociatedObject(self, CEBackupKey, backup, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#pragma mark - Methods
- (void)restoreBackup {
    [self removeAllObjects];
    [self addObjectsFromArray:self.backup];
}
@end

任何人都可以详细解释这里发生了什么......

并且这种存储备份的方式会占用更少的内存,而不是拥有此阵列的单独深层副本......?

1 个答案:

答案 0 :(得分:0)

objc_setAssociatedObject允许您将值与对象 - 密钥对相关联。可以把它想象成与每个对象相关联的隐式全局NSMutableDictionary。事实上,在将关联对象添加到运行时之前,单例字典词典将是实现相同事物的一种方式。这是一个简化的示例,说明如何自己实现它,忽略类加载,线程安全以及如何正确使用对象作为字典键等问题:

// Returns the global dictionary-of-dictionaries for associated objects
static NSMutableDictionary* getAssociationDict () {
    static dispatch_once_t once;
    static NSMutableDictionary* dict;
    dispatch_once(&once, ^{ dict = [[NSMutableDictionary alloc] init]; });
    return dict;
}

id my_objc_getAssociatedObject (id object, NSString* key) {
    return [[getAssociatedDict() objectForKey:object] objectForKey:key];
}

void my_objc_setAssociatedObject(id object, NSString* key, id value) {
    NSMutableDictionary* dict = getAssociationDict();
    NSMutableDictionary* objectDict = [dict objectForKey:object];
    // Create the per-object dictionary if it's missing
    if (! objectDict) {
        objectDict = [[NSMutableDictionary alloc] init];
        [dict setObject:objectDict forKey:object];
    }
    [objectDict setObject:value forKey:key];
}

虽然上述内容实际上不起作用,但它概述了如何完成。