談?wù)凮C中的循環(huán)引用

1.什么時(shí)候會(huì)發(fā)生循環(huán)引用

將一個(gè)提前準(zhǔn)備好的代碼塊, 在需要執(zhí)行的時(shí)候立即執(zhí)行, 在不需要立即執(zhí)行的時(shí)候, 用個(gè)屬性將這個(gè)函數(shù)傳遞過來的block記錄下來, 產(chǎn)生了強(qiáng)引用, 此時(shí)就會(huì)發(fā)生循環(huán)引用

2.怎么解決循環(huán)引用

那么怎么解決循環(huán)引用, 就是打破任一方的強(qiáng)引用

.

  • 其中使用最多的就是__weak, 聲明一個(gè)弱引用類型的自己, 解除循環(huán)引用, 其中__weak跟weak類似, 當(dāng)對象被系統(tǒng)回收時(shí), 它的內(nèi)存地址會(huì)自動(dòng)指向nil, 對nil進(jìn)行任何操作不會(huì)有反應(yīng)

  • 但其實(shí)在ios4的時(shí)候, 也可以使用__unsafe_unretained, 解除強(qiáng)引用, 但是它存在一定的不安全性, 原理和assign類似, 當(dāng)對象被系統(tǒng)回收時(shí), 它的內(nèi)存地址不會(huì)自動(dòng)指向nil, 就有可能出現(xiàn)壞內(nèi)存地址的訪問, 也就發(fā)生野指針錯(cuò)誤

  • 在之前發(fā)現(xiàn)了很多解除循環(huán)引用的時(shí)候, 會(huì)先使用__weak, 聲明自己為弱引用類型, 然后在準(zhǔn)備好的代碼塊中也就是block中, 再對弱引用對象利用__strong 做一次強(qiáng)操作 , 仔細(xì)驗(yàn)證發(fā)現(xiàn)再做強(qiáng)引用操作是冗余的, 并不會(huì)產(chǎn)生影響, 可以不用寫

3.如何驗(yàn)證是否發(fā)生循環(huán)引用

.

4.simple demo

#import "ViewController.h"
#import "NetworkTools.h"


@interface ViewController ()
@property (nonatomic, strong) NetworkTools *tools;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tools = [[NetworkTools alloc] init];
   
/*
    //解決方式三: __unsafe_unretained 不推薦, 不安全
    __unsafe_unretained typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        __strong typeof(self) strongSelf = weakSelf;
        NSLog(@"%@%@",html,strongSelf.view);
        strongSelf.view.backgroundColor = [UIColor redColor];
    }];
*/

    //解決方式二: __weak
    __weak typeof(self) weakSelf = self;
    [self.tools loadData:^(NSString *html) {
        __strong typeof(self) strongSelf = weakSelf;
        NSLog(@"%@%@",html,strongSelf.view);
        strongSelf.view.backgroundColor = [UIColor redColor];
    }];
    
}

//解決方式一: 
- (void) method1{
    NetworkTools *tools = [[NetworkTools alloc] init];
    [tools loadData:^(NSString *html) {
        NSLog(@"%@%@",html,self.view);
        self.view.backgroundColor = [UIColor redColor];
    }];
}

- (void)dealloc {
    NSLog(@"VC dealloc");
}
@end

#import "NetworkTools.h"

@interface NetworkTools ()

//用一個(gè)屬性 來記錄 函數(shù)傳遞過來的 block
@property (nonatomic, copy) void(^finishedBlock)(NSString *);

@end

@implementation NetworkTools

- (void)loadData:(void (^)(NSString *))finishedCallBack {
   
    //開始記錄blcok
    self.finishedBlock = finishedCallBack;

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
     
        [NSThread sleepForTimeInterval:3];
      
        //開始耗時(shí)任務(wù)
        NSLog(@"開始加載數(shù)據(jù)");
        
        dispatch_async(dispatch_get_main_queue(), ^{
            //調(diào)用方法
            [self working];
        });
    }); 
}

- (void) working {
    //執(zhí)行block
    if (self.finishedBlock) {
        self.finishedBlock(@"<html>");
    }
}

- (void)dealloc {
    NSLog(@"Tools dealloc");
}

@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 《Objective-C高級編程》這本書就講了三個(gè)東西:自動(dòng)引用計(jì)數(shù)、block、GCD,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 9,885評論 10 69
  • 那個(gè)穿藍(lán)色白條紋褲,上身穿黑色T恤,綁個(gè)馬尾辮在設(shè)備部的姑娘,我想認(rèn)識你呀!哈哈,哈哈,你好漂亮!
    leyes閱讀 172評論 0 0
  • 百無聊賴地躺在床上,心情有點(diǎn)煩悶。都重陽了,暑意沒有一點(diǎn)兒要消退的意思,蛐蛐叫了一夏,還不知道夏季已過。全球變暖似...
    種花家吳嶺閱讀 233評論 0 0
  • 啃《西方哲學(xué)史》洛克的政治學(xué)說一章,看時(shí)突然有些模糊地理解,所有這些理論,包括勞動(dòng)價(jià)值說、咱從小學(xué)的馬克思那一套啥...
    Allul閱讀 711評論 0 1
  • 寫這篇文章,醞釀了很久。是自己的切身體會(huì),也是對生活的反思。雖然醞釀已久,但并未有很強(qiáng)的邏輯性。算是一篇隨筆。 我...
    愛逗子閱讀 731評論 4 8