1. 程式人生 > >block解決迴圈引用(一)

block解決迴圈引用(一)

看了網上的一些資料,感覺暈乎乎的,還不是很明白。自己抽了一個下午仔細的研究了一下block,嗯,明白了好多。分兩次寫出來,歡迎大家交流。
這裡不討論底層,不討論原理,注重實用!

什麼是block?

閉包(block):閉包就是獲取其他函式區域性變數的匿名函式。

block格式:

返回值型別(^block變數名)(形參列表) = ^(形參列表) {

 };

 //有引數無返回值
    void (^myBlock)(NSString* ) = ^(NSString *myBlockStr){
        NSLog(@"%@",myBlockStr);
    };

    myBlock(@"safeed"
); //有引數有返回值 NSString* (^myBlock1)(NSString* ) = ^(NSString *myBlockStr){ NSLog(@"%@",myBlockStr); return @"我是返回值"; }; NSLog(@"%@",myBlock1(@"引數值"));

什麼情況下會造成迴圈引用?

當前控制器引用著block,block引用這當前控制器,就會造成迴圈引用。

避免迴圈引用詳解

typedef void (^MyBlock)(NSString *myBlockStr);
@interface
ViewController ()
@property (nonatomic,strong)MyBlock myBlock; 這裡聲明瞭一個帶引數不帶返回值的block
//1.不會迴圈引用
    self.myBlock = ^(NSString *myBlockStr) {
        NSLog(@"%@",myBlockStr);
    };
    //self引用了myBlock,但是在myBlock並沒有self什麼事情,只是列印了一下引數myBlockStr,並不會造成迴圈引用
    self.myBlock(@"myBlockStr201");

1.通過Leaks可以看到,是沒有記憶體洩露的
這裡寫圖片描述

//2.會迴圈引用
    self.myBlock = ^(NSString *myBlockStr) {

        NSLog(@"%@",self.str);
        NSLog(@"%@",self.str = myBlockStr);

    };
    //這個就是典型的block迴圈引用了,self引用了myBlock,myBlock內部引用了self,想要解除迴圈引用,需要在block外部弱引用一下self, __weak typeof(self) weakSelf = self;
    self.myBlock(@"myBlockStr202");

2.通過Leaks可以看到,有記憶體洩露
這裡寫圖片描述

  //3.解除迴圈引用
    __weak typeof(self) weakSelf = self;

    self.myBlock = ^(NSString *myBlockStr) {

        NSLog(@"%@",weakSelf.str);
        NSLog(@"%@",weakSelf.str = myBlockStr);

    };

    self.myBlock(@"myBlockStr203");

    //4.block內修改外部變數
    __block NSString *myStr = @"2000q";

    self.myBlock = ^(NSString *myBlockStr) {

        myStr = @"200a";
        NSLog(@"%@",myBlockStr);
        NSLog(@"%@",myStr);
    };
    //Block不允許修改外部變數的值,這裡所說的外部變數的值,指的是棧中指標的記憶體地址。__block 所起到的作用就是隻要觀察到該變數被 block 所持有,就將“外部變數”在棧中的記憶體地址放到了堆中。進而在block內部也可以修改外部變數的值
    self.myBlock(@"myBlockStr204");
//5.block的簡單使用升級
這裡在viewController裡面匯入一個Persopn類,裡面有一個block
typedef void (^MyBlock)(NSString * str);
@property(nonatomic,strong)MyBlock myBlock;

在viewController
@property(nonatomic,strong)NSString *str;
@property (nonatomic,strong)Person *person;

 self.person.myBlock = ^(NSString *str) {

            NSLog(@"%@",self.person.personStr);
            NSLog(@"%@",self.person);
            NSLog(@"%@",self.str);
            NSLog(@"%@",self.str = str);
        };
//這種也會造成迴圈引用,想要解決請參照3

由於時間的原因,先寫這麼多,附上demo的下載地址(https://github.com/2877025939/block)。
(二)會增加反向傳值,block在物件方法中的使用。
歡迎大家交流,qq:2877025939.