ios中的循环引用
来源:互联网 发布:端口地址查询位置 编辑:程序博客网 时间:2024/05/21 18:00
ios中的循环引用
在ios中使用
block (闭包)
的时候,代码块中使用到self 有可能出现循环引用循环引用的两种形式:
- 多个对象循环强引用,都不能释放,导致内存泄露
- 单例强引用其他对象,由于单例不会被释放销毁,程序结束时才会销毁,导致其他对象不能及时销毁
OC中的循环引用
- 建立
NetworkTools
类
@interface NetworkTools ()@property (nonatomic, strong) void(^finishedBlock)();@end@implementation NetworkTools- (void)loadDataWithFinishBlock:(void (^)())finishBlock { self.finishedBlock = finishBlock; [self work];}- (void)work { if (self.finishedBlock) { self.finishedBlock(); }}- (void)dealloc { NSLog(@"%@ dealloc",self);}@end
- 示例化
NetworkTools
并加载数据
@interface ViewController ()@property (nonatomic, strong) NetworkTools *networkTools;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.networkTools = [NetworkTools new]; [self.networkTools loadDataWithFinishBlock:^(){ NSLog(@"%@",self.view); }];}- (void)dealloc { NSLog(@"%@ dealloc",self);}@end
运行测试会出现循环引用
- 原因:
- viewController ==> networkTools ==> finishedBlock ==> self(viewController)
- ==> 表示强引用
解除循环引用
使用
__weak typeof(self) weakSelf = self;
- 如果self 被释放,weakSelf 的地址将改为nil
- (void)viewDidLoad { [super viewDidLoad]; self.networkTools = [NetworkTools new]; __weak typeof(self) weakSelf = self; [self.networkTools loadDataWithFinishBlock:^(){ NSLog(@"%@",weakSelf.view); }];}
- 使用
__unsafe_unretained typeof(self) weakSelf = self;
- weakSelf 是assign,当self被释放时,weakSelf 的地址不会改变,可能会出现野指针错误
- (void)viewDidLoad { [super viewDidLoad]; self.networkTools = [NetworkTools new]; __unsafe_unretained typeof(self) weakSelf = self; [self.networkTools loadDataWithFinishBlock:^(){ NSLog(@"%@",weakSelf.view); }];}
- 推荐使用
__weak
的方式解决OC中的循环引用
swift 中的循环引用
- 建立
NetworkTools
类
class NetworkTools1: NSObject { var finishedCallBack: (() -> ())? func loadData(finishedCallBack: () -> ()) { dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in print("加载数据") NSThread.sleepForTimeInterval(2) self.finishedCallBack = finishedCallBack; self.work() } } func work() { finishedCallBack?() } deinit { print("\(self) deinit") }}
- 示例化
NetworkTools
并加载数据
class ViewController1: UIViewController { var networkTools: NetworkTools1? override func viewDidLoad() { super.viewDidLoad() networkTools = NetworkTools1() networkTools?.loadData({ () -> () in print("\(self.view)") }) } deinit { print("\(self) deinit") }}
运行测试会出现循环引用
- 原因:
- ViewController1 ==> networkTools ==> finishedCallBack ==> self(ViewController1)
解除循环引用
- 使用
weak
- 当self释放时,weakSelf为变为 nil
weak var weakSelf = self networkTools?.loadData({ () -> () in print("\(weakSelf?.view)") })
- 使用
[weak self]
- 闭包中的self是可选项,当self 被释放时,
self?
不执行,更安全
- 闭包中的self是可选项,当self 被释放时,
networkTools?.loadData({[weak self] () -> () in print("\(self?.view)") })
- 使用
[unowned self]
- self 不是可选项,如果self 已经被释放,则会出现野指针错误
networkTools?.loadData({[unowned self] () -> () in print("\(self.view)") })
- swift 中推荐使用
[weak self]
解决循环引用
0 0
- ios中的循环引用
- iOS开发中的循环引用问题
- 浅谈iOS中的循环引用问题
- iOS | 小心NSTimer中的循环引用
- ios避免循环引用
- iOS循环引用
- ios delegate循环引用
- iOS之循环引用
- iOS 循环引用问题
- iOS内存循环引用
- iOS解决循环引用
- iOS 循环引用
- iOS 循环引用问题
- iOS循环引用问题
- iOS循环引用
- 关于ios循环引用
- 关于IOS,多线程Block中的self循环引用问题!
- oc中的循环引用
- 获得网络图片
- hdu2048
- 删除二叉查找树的节点
- 分享
- jdk安装与环境变量配置
- ios中的循环引用
- redis(1):redis在不同平台下的安装方法及配置
- 这些育儿经,80%的父母不知道!
- 屏幕锁定四个方向
- [搬运]扫盲 HTTPS 和 SSL/TLS 协议
- 《剑指offer》-替换空格
- UITableViewCell加载网络图片自适应cell高度初探索
- HDU3533 - Escape
- XMind和MindManager,思维导图软件学习使用心得