搜尋

首頁  >  問答  >  主體

ios - 类方法中使用了block,如何避免循环引用?

代码如下,在netRequestCallBack的中的使用了vc,Xcode会告警提示: 可能导致循环引用。 请问如何消除?

+ (void)JumpToMe {
    dispatch_async(dispatch_get_main_queue(), ^{
    AUIViewController *vc = [[AUIViewController alloc] init];
    vc.mainModel.netRequestCallBack = ^(NSError *error){
        [[vc navigationController] pushViewController:vc animated:YES];
    };
    [vc.mainModel sendNetworking];
    });
}

尝试:

  1. vc使用修饰词 __block,但不能解决问题,而且__block修饰后,vc仍然是强引用的。

  2. vc使用修饰词__weak,确实消除了Xcode关于循环引用的告警。但netRequestCallBack 运行时,会发现vc已经被为nil
    我理解出现这种情况,是在类方法完成后,vc没有了持有者了,也是被释放了。

所以,请问有什么方法可以解决这个吗?

PHP中文网PHP中文网2771 天前857

全部回覆(4)我來回復

  • 迷茫

    迷茫2017-04-18 09:57:43

    是否是循環引用與呼叫方法無關,只與引用關係有關。

    在你的例子中,引用環為 vc --> mainModel --> netRequestCallBack --> vc。 ("-->"表示引用關係)

    物件被釋放的先決條件為該物件不被其他物件持有。而你的例子中vc被netRequestCallBack持有,所以不會被釋放

    打破引用環的辦法為使用__weak來宣告被block捕捉的變數。

    __weak AUIViewController *tmpVC = vc;
    vc.mainModel.netRequestCallBack = ^(NSError *error){
        [[tmpVC navigationController] pushViewController:vc animated:YES];
    };

    而對於vc被釋放的問題,在於vc沒有被別的對象持有。正確的解決方法應該是從目前navigaionController或別的vc堆疊中,找出該vc,然後對該vc進行操作。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-18 09:57:43

    block屬性用copy,然後加上__strong __typeof(weaksSelf) strongSelf = weakSelf,不過你程式碼邏輯好怪

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 09:57:43

    在你的block裡用__strong __typeof(&*weaksSelf) strongSelf = weakSelf修飾

    回覆
    0
  • 高洛峰

    高洛峰2017-04-18 09:57:43

    先不說循環引用的問題

    [[vc navigationController] pushViewController:vc animated:YES];
    

    就這一句就有問題 vc沒被push vc.navigationController會不為Nil? vc.navgationController 為nil的話 能push vc?

    回覆
    0
  • 取消回覆