1、关联对象模拟weak的实现,自动置空
- NSObject+weak.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSObject (weak)
@property(nonatomic,weak)id weakObjc;
@end
NS_ASSUME_NONNULL_END
- NSObject+weak.m
#import "NSObject+weak.h"
#import <objc/runtime.h>
typedef void (^DeallocBlock)(void);
@interface NSObject (weak)
@property(nonatomic,copy)DeallocBlock block;
@end
@implementation NSObject (weak)
- (id)weakObjc {
return objc_getAssociatedObject(self, @selector(weakObjc));
}
- (void)setWeakObjc:(id)weakObjc {
//⚠️注意 此处是 把block赋值给了weakObjc 把block当中间变量。
[weakObjc setBlock:^{ //B关联了A中的weakObjc。当B对象释放的时候就会通过A去找weakObjc。所以会触发A的dealloc
objc_setAssociatedObject(self, @selector(weakObjc), nil, OBJC_ASSOCIATION_ASSIGN);
}];
objc_setAssociatedObject(self, @selector(weakObjc), weakObjc, OBJC_ASSOCIATION_ASSIGN);
}
- (DeallocBlock)block {
return objc_getAssociatedObject(self, @selector(block));
}
- (void)setBlock:(DeallocBlock)block {
objc_setAssociatedObject(self, @selector(block), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" //未使用default
- (void)dealloc {
self.block?self.block():nil; //weakObjc置空
objc_setAssociatedObject(self, @selector(block), nil,OBJC_ASSOCIATION_COPY_NONATOMIC);//block置空
}
#pragma clang diagnostic pop
@end
-
测试使用
NSObject *obj1 = [NSObject new]; NSObject *obj2 = [NSObject new]; obj1.weakObjc = obj2; NSLog(@"Feng %@",obj1.weakObjc); obj2 = nil; //obj2持有obj1中的weakObjc。obj2为nil会调用obj2的dealloc,会通过obj1去找weakObjc,触发obj1的dealloc NSLog(@"Feng %@",obj1.weakObjc);
-
输出结果
2022-06-01 08:29:39.132352+0800 Demo[2495:44993] Feng <NSObject: 0x600001ac1680> 2022-06-01 08:29:39.132563+0800 Demo[2495:44993] Feng (null)
参考连接:https://www.jianshu.com/p/df5bd59f14c1
文章持续更新中、希望对各位有所帮助、有问题可留言 大家共同学习.
网友评论