Instantly share code, notes, and snippets.

Embed
What would you like to do?
iOS 实现弱引用数组的几种方法
//
// main.m
// iOS 实现弱引用数组
//
// Created by TsuiYuenHong on 2017/4/10.
// Copyright © 2017年 TsuiYuenHong. All rights reserved.
//
#import <Foundation/Foundation.h>
// 方法 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;
}
@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
unsigned long retainCount(NSObject *obj){
// under MRC
return [obj retainCount];
// under ARC
// return CFGetRetainCount((__bridge CFTypeRef)obj);
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 测试数据
NSArray *obj1 = @[@"👌",@"🌎"];
NSArray *obj2 = @[@"👌",@"🌎"];
NSDictionary *obj3 = @{
@"👌":@"🌎",
};
NSLog(@"Before\n\
obj1 : %lu\n\
obj2 : %lu\n\
obj3 : %lu\n",retainCount(obj1),retainCount(obj2),retainCount(obj3));
NSMutableArray *strongMArray = [NSMutableArray array];
[strongMArray addObject:obj1];
[strongMArray addObject:obj2];
[strongMArray addObject:obj3];
[strongMArray unretainedAddObj:obj1];
[strongMArray unretainedAddObj:obj2];
[strongMArray unretainedAddObj:obj3];
[strongMArray addObject:weakRef(obj1)];
[strongMArray addObject:weakRef(obj2)];
[strongMArray addObject:weakRef(obj3)];
NSLog(@"Value\n\
obj1 : %@\n\
obj2 : %@\n\
obj3 : %@\n", getWeakObj([strongMArray objectAtIndex:6]),
getWeakObj([strongMArray objectAtIndex:7]),
getWeakObj([strongMArray objectAtIndex:8]));
NSMutableArray *weakMArray = [NSMutableArray unreatainedArray];
[weakMArray addObject:obj1];
[weakMArray addObject:obj2];
[weakMArray addObject:obj3];
NSLog(@"After\n\
obj1 : %lu\n\
obj2 : %lu\n\
obj3 : %lu\n",retainCount(obj1),retainCount(obj2),retainCount(obj3));
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment