美文网首页iOS精品文章
iOS 实现弱引用数组的几种方法

iOS 实现弱引用数组的几种方法

作者: Tsui_YuenHong | 来源:发表于2017-04-10 18:47 被阅读343次

    源于一道面试题的总结,由于要观察引用计数,所以以下代码都是基于 MRC 的 (其中 ARC 的代码也在注释里面)。

    利用 block

    注意 ARC 和 MRC 下的区别

    // 方法 1 利用 block
    typedef id(^WeakRefBlock)(void);
    
    WeakRefBlock weakRef (id obj) {
    //     under MRC
        __unsafe_unretained id weakObj = obj;
        return [^{
            return weakObj;
        } copy];
    
    //     under ARC
    //    __weak id weakObj = obj;
    //    return ^{
    //        return weakObj;
    //    };
    }
    
    id getWeakObj(WeakRefBlock block){
        if (block && [block isKindOfClass:NSClassFromString(@"NSBlock")]) {
            return block();
        }
    
        return nil;
    }
    

    利用 CFArrayCreateMutable 或者 NSValue

    @interface NSMutableArray (WeakRef)
    
    // 方法 2 利用 CFArrayCreateMutable
    // 初始化即是 weak array
    + (instancetype) unreatainedArray;
    
    // 方法 3 利用 NSValue
    // 添加 unretained 数据
    - (void) unretainedAddObj:(NSObject *)obj;
    // 获取 unretained 数据
    - (NSObject *) unretainedObjectAtIndex:(NSUInteger)index;
    
    @end
    
    @implementation NSMutableArray (WeakRef)
    
    + (instancetype) unreatainedArray {
        CFArrayCallBacks callbacks = {0, NULL, NULL, CFCopyDescription, CFEqual};
        return (id)CFBridgingRelease(CFArrayCreateMutable(0, 0, &callbacks));
    }
    
    - (void)unretainedAddObj:(NSObject *)obj {
        NSValue *value = [NSValue valueWithNonretainedObject:obj];
        [self addObject:value];
    }
    
    - (NSObject *)unretainedObjectAtIndex:(NSUInteger)index {
        NSValue *value = [self objectAtIndex:index];
        return [value nonretainedObjectValue];
    }
    
    @end
    

    最后

    使用弱引用数组记得要对取值进行检查,防止因为引用对象被释放的情况出现的 crash !

    完整的代码请看 gist (ง •̀_•́)ง

    相关文章

      网友评论

      本文标题:iOS 实现弱引用数组的几种方法

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