国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Objective-C——Block

2019-11-14 18:35:34
字體:
來源:轉載
供稿:網友

OC Block 其實功能就類似C語言的函數指針,js中的閉包之類的。把代碼塊當做一個變量就行操作,有自己的變量和作用域。

簡單看一下Block的語法和可能出現的問題:

 

Block語法:

block語法相對寬松,很多部分都可以省略,常規上我們實現一個block需要有以下幾個部分

^ 返回值類型 參數列表 表達式

例如

    ^int (int count){return count+1;};//返回值為int 參數為int 表達式為 count+1;    ^void (void){NSLog(@"void");};    //返回值為void 參數void 表達式為  NSLog(@"void");

可以看到語法相對簡單,而且返回值類型可以省略那么以上兩個block就變

    ^(int count){return count+1;};    ^(void){NSLog(@"void");};

如果不適用參數,那么返回值列表也可以省略

    ^(int count){return count+1;};    ^{NSLog(@"void");};

 

Block類型變量

Blcok類型的變量可以接受對應的Block,上例中兩個Block就需要以下兩種Block類型變量接收

    int (^intBlock)(int) = ^(int count){return count+1;};    void (^voidBlock)(void) = ^{NSLog(@"void");};

上例中,可以看到變量定義格式

返回值類型 (^變量名稱) (返回值類型)

如果嫌這種定義方式麻煩的話,可以使用typedef來簡化定義方式

    typedef int (^typedefBlock) (int);    typedefBlock block = ^(int count){return count+1;};

 

截獲變量值

Block中,可以使用調用Block之前的變量的值,例如

    int a = 5;    int (^intBlock)(int) = ^(int count){return count+a;};    NSLog(@"%d",intBlock(5));    2015-08-02 17:25:53.393 Dispatch[9970:3096937] 10

可以看到輸出結果是10,說明intBlock截獲了變量a的值。

但是如果我們想要修改a的值,就會出現錯誤可以自己嘗試一下。

想要修改需要在變量前添加__block修飾符,說明該變量在block中是可以被修改的。

    __block int a = 5;    int (^intBlock)(int) = ^(int count){a = 3; return count+a;};    NSLog(@"%d",intBlock(5));    2015-08-02 17:33:11.629 Dispatch[10118:3136172] 8

輸出結果為8,說明已經被我們修改了。

同樣的道理,對已OC對象來說也是,如果調用方法使用該變量可以,但是對變量進行賦值操作就需要加上__block修飾符。

 

Block循環引用

循環引用出現條件,該對象持有Block的成員屬性,同時在Block中使用self。這樣會造成Block和對象之間的相互引用,互相都無法釋放,形成內存泄露。

@interface ViewController (){    voidBlock _voidBlock;}- (void)viewDidLoad {    [super viewDidLoad];       // __block int a = 5;    _voidBlock = ^{NSLog(@"%@",self);};    _voidBlock();}

 這樣寫編譯去會提示我們self的強引用在Block中使用。

還有一種,如果我們在Block中使用了成員屬性,同樣會造成內存泄露。因為成員屬性是self指針指向的對象,還是在Block中持有了self。

 

__weak
為了避免這樣的情況發生,我們再上面的例子中稍微修改一下

- (void)viewDidLoad {    [super viewDidLoad];       // __block int a = 5;    __weak ViewController *temp = self;    _voidBlock = ^{NSLog(@"%@",temp);};    _voidBlock();}

使用弱引用對象就能很好的避免這種情況。

再有就是用__block也能夠避免循環。

- (void)viewDidLoad {    [super viewDidLoad];       // __block int a = 5;    __block ViewController *temp = self;    _voidBlock = ^{NSLog(@"%@",temp); temp = nil;};    _voidBlock();}

注意這樣寫必須調用該Block,執行Block代碼才行,如果不執行還是會造成內存泄露。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲周县| 新营市| 宕昌县| 陇南市| 黑龙江省| 蓬溪县| 夏河县| 荃湾区| 永宁县| 普安县| 台山市| 黎川县| 永清县| 德格县| 新沂市| 开远市| 萝北县| 永胜县| 永安市| 佛坪县| 铁岭市| 蓝山县| 疏附县| 泽州县| 进贤县| 德格县| 年辖:市辖区| 南华县| 宜宾市| 锦屏县| 凤山县| 大埔县| 图们市| 扬中市| 和政县| 阜南县| 根河市| 自贡市| 汤原县| 凤庆县| 邢台县|