block之---循環參考

來源:互聯網
上載者:User

標籤:

block內部引用外界對象的原則:block會對他內部所有的強指標進行強引用。驗證原理:

在主控制器中modal出ModalVC控制器,ModalVC中有強引用的block屬性,在block內部使用self,此時ModalVC便不會被釋放,不會執行dealloc方法。

驗證代碼:

循環參考的情況:

#import "ModalVC.h"@interface ModalVC ()// block屬性@property (nonatomic, strong) void(^block)();@end@implementation ModalVC- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor orangeColor];    // 定義block屬性    self.block = ^{        NSLog(@"%@", self);    };    // 調用block    self.block();}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {    // 返會上一層控制器    [self dismissViewControllerAnimated:YES completion:nil];}- (void)dealloc {    NSLog(@"ModalVC is release");}@end

改進方法: 將建立一個弱引用的self,供block內部使用

- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor orangeColor];    // 建立弱引用的self    __weak typeof(self) weakSelf = self;    // 定義block屬性    self.block = ^{        NSLog(@"%@", weakSelf);    };    // 調用block    self.block();}
block在多線程中問題block中使用的對象可能會被提前釋放。
#import "ModalVC.h"@interface ModalVC ()// block屬性@property (nonatomic, strong) void(^block)();@end@implementation ModalVC- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor orangeColor];    // 建立弱引用的self    __weak typeof(self) weakSelf = self;    // 定義block屬性    self.block = ^{        // 延時執行        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            NSLog(@"%@", weakSelf);        });    };    // 調用block    self.block();}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {    // 返會上一層控制器    [self dismissViewControllerAnimated:YES completion:nil];}- (void)dealloc {    NSLog(@"ModalVC is release");}@end

在此種情況下,在ModalVC被modal出來後立即點擊螢幕,列印結如下,說明ModalVC在延時中的block執行時已經被提前釋放了,這種情況並不是我們想要的。

2016-01-16 10:06:19.206 004-block的循環參考問題[1863:54052] ModalVC is release2016-01-16 10:06:19.547 004-block的循環參考問題[1863:54052] (null)

記憶體分析

 

當ModalVC被VC控制器modal出來時,它被VC的presentedViewController屬性強引用,當點擊螢幕時,ModalVC控制器被dismiss掉了,presentedViewController強指標就無效了,ModalVC因為沒有強指標指向,就會被釋放掉,block也會被釋放掉,但是dispatch_after中的Block並沒有被釋放(被系統強引用著),兩秒後執行時列印出的weakSelf就為nil。

解決方案: 

在block對象中再對weakSelf增加一個強指標

- (void)viewDidLoad {    [super viewDidLoad];    self.view.backgroundColor = [UIColor orangeColor];    // 建立弱引用的self    __weak typeof(self) weakSelf = self;    // 定義block屬性    self.block = ^{        // 給weakSelf增加一個強指標        __strong typeof(self) strongSelf = weakSelf;        // 延時兩秒        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{            NSLog(@"%@", strongSelf);        });    };    // 調用block    self.block();}

執行結果, 先列印ModalVC控制器,再釋放ModalVC控制器

2016-01-16 10:57:16.837 004-block的循環參考問題[2113:80213] <ModalVC: 0x7fdcd1d26850>2016-01-16 10:57:16.838 004-block的循環參考問題[2113:80213] ModalVC is release

記憶體分析 

當點擊螢幕時,ModalVC控制器被dismiss掉了,presentedViewController強指標就無效了,但是ModalVC控制器仍然會被dispatch_after中block的strongSelf所強引用,所以不會被釋放掉。

 

block之---循環參考

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.