簡單談?wù)凚lock

 * author:conowen@大鐘                                                                                                                          
 * E-mail:conowen@hotmail.com      

1、Block的定義

Block是Objc赘艳、C、C++的一個語言級別擴充功能辆脸,Block其實就是一塊代碼段但校,你可以很方便地把一個代碼段傳遞到不同的方法里面或者不同的類,就像傳值一樣方便啡氢。Block可以當做Objc里面的一個對象状囱。(也就是說,你可以把它當做一個類似NSString的對象)

2倘是、Block的聲明

//As a local variable:  
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};  

//As a property:  
@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);  

//As a method parameter:  
  
- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;  

//As an argument to a method call:  
[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];  

//As a typedef:  
typedef returnType (^TypeName)(parameterTypes);  
TypeName blockName = ^returnType(parameters) {...};  

上述定義來源

http://fuckingblocksyntax.com/

3亭枷、Block聲明詳解

其實Block的定義有點類似函數(shù)指針

引申:指針函數(shù)與函數(shù)指針的區(qū)別

  • a、指針函數(shù)
    表示函數(shù)返回值是一個指針類型搀崭,定義如下
//類型標識符  *函數(shù)名(參數(shù)表)  
int *fun(x叨粘,y);  
  • b猾编、函數(shù)指針
    表示指向這個函數(shù)的指針變量,定義如下
類型標識符  (*函數(shù)名)(參數(shù)表)  

int (*fun) (int x,y); //函數(shù)名前面有一個星號升敲,然后用小括號包起來  
fun=funTest; /* 將funTest函數(shù)的首地址賦給指針  

而Block就是
int (^fun) (int,int);

3答倡、Block的應(yīng)用場景

3.1、定義一個Block驴党,然后輸出打印信息

int (^addFun)(int,int) = ^int(int a,int b){  
  
    return a + b;  
};  
  
NSLog(@"addValue = %d",addFun(1,2));  

打印消息是
2016-06-01 11:27:14.191 Runtime[10910:4558911] addValue = 3

3.2瘪撇、Block與Delegate的區(qū)別

這是最簡單的Block使用,一般我們使用Block來做一些有趣的事情港庄,例如代替delegate倔既,平常我們在不同的類傳值的話,一般使用delegate鹏氧,雖然也能實現(xiàn)渤涌,但是寫法比較繁瑣,用Block就能很輕松實現(xiàn)度帮,而且代碼量少了不少歼捏。
下面的小Demo就依次對比了Delegate與Block在不同類的傳值的區(qū)別

第一個ViewController的代碼如下


//  
//  ViewController.m  
//  Runtime  
//  
//  Created by idealMac2 on 16/5/20.  
//  Copyright ? 2016年 GValley. All rights reserved.  
//  
  
#import "ViewController.h"  
#import "SecondViewController.h"  
  
@interface ViewController () <SecondViewControllerDelegate>  
  
@end  
  
@implementation ViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
    // Do any additional setup after loading the view, typically from a nib.  
      
      
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 60.0, 20.0)];  
    [btn setTitle:@"open" forState:UIControlStateNormal];  
    [btn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];  
    [btn addTarget:self action:@selector(openAction:) forControlEvents:UIControlEventTouchUpInside];  
    [self.view addSubview:btn];  
}  
  
- (void)openAction:(id)sender{  
    NSLog(@"openAction");  
    SecondViewController *secondViewController = [SecondViewController new];  
    secondViewController.callBackValue =  ^ void (NSString *str){  
        NSLog(@"Block str = %@",str);  
       
    };  
    secondViewController.delegate = self;  
    [self presentViewController:secondViewController animated:YES completion:nil];  
  
}  
  
#pragma mark SecondViewControllerDelegate  
- (void)closeAction:(NSString *) str{  
  
    NSLog(@"delegate str = %@",str);  
}  
  
- (void)didReceiveMemoryWarning {  
    [super didReceiveMemoryWarning];  
    // Dispose of any resources that can be recreated.  
}  
  
@end  

第二個ViewController的頭文件如下

//  
//  SecondViewController.h  
//  Runtime  
//  
//  Created by idealMac2 on 16/6/1.  
//  Copyright ? 2016年 GValley. All rights reserved.  
//  
  
#import <UIKit/UIKit.h>  
//聲明delegate  
@protocol SecondViewControllerDelegate <NSObject>  
  
@optional  
- (void)closeAction:(NSString *) str;  
  
@end  
  
@interface SecondViewController : UIViewController  
//聲明Block  
@property (nonatomic,copy) void(^callBackValue)(NSString *);  
  
@property (nonatomic,weak) id<SecondViewControllerDelegate>  delegate;  
@end  

第二個ViewController的實現(xiàn)文件如下


//  
//  SecondViewController.m  
//  Runtime  
//  
//  Created by idealMac2 on 16/6/1.  
//  Copyright ? 2016年 GValley. All rights reserved.  
//  
  
#import "SecondViewController.h"  
  
@interface SecondViewController ()  
  
@end  
  
@implementation SecondViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
    // Do any additional setup after loading the view.  
      
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 60.0, 20.0)];  
    [btn setTitle:@"close" forState:UIControlStateNormal];  
    [btn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];  
    [btn addTarget:self action:@selector(closeAction:) forControlEvents:UIControlEventTouchUpInside];  
    [self.view addSubview:btn];  
}  
  
- (void)closeAction:(id)sender{  
  
      
    NSString *strA = @"closed";  
    //Block的方式  
    self.callBackValue(strA);  
      
    //Delegate的方式  
    if (self.delegate && [self.delegate respondsToSelector:@selector(closeAction:)]) {  
        [self.delegate closeAction:strA];  
    }  
     
    [self dismissViewControllerAnimated:YES completion:nil];  
   
}  
  
  
  
  
- (void)didReceiveMemoryWarning {  
    [super didReceiveMemoryWarning];  
    // Dispose of any resources that can be recreated.  
}  
  
/* 
#pragma mark - Navigation 
 
// In a storyboard-based application, you will often want to do a little preparation before navigation 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // Get the new view controller using [segue destinationViewController]. 
    // Pass the selected object to the new view controller. 
} 
*/  
  
@end  

打印消息如下

2016-06-01 12:10:31.211 Runtime[10959:4573582] block str = closed
2016-06-01 12:10:31.211 Runtime[10959:4573582] delegate str = closed

4、Block與外部變量的關(guān)系

我們知道笨篷,Block有一個神奇之處瞳秽,它可以直接使用Block之外的變量,如下面的代碼率翅。

int c = 0;  
  
int (^addFun)(int,int) = ^int(int a,int b){  
    return a + b + c;  
};  
NSLog(@"addValue = %d",addFun(1,2));  

但是如果要修改外部變量练俐,就會出現(xiàn)無法修改的問題,同時冕臭,使用外部變量腺晾,也會存在引起循環(huán)引用的問題。

4.1辜贵、如何修改Block外部變量

解決這個問題有兩種方法:
一種是C語言的方法悯蝉,因為C語言中的靜態(tài)變量、靜態(tài)全局變量托慨,全局變量是允許Block修改其值的鼻由。因為“全局變量” 和“ 全局靜態(tài)變量” 由于作用域是全局,所以在 Block 內(nèi)訪問和讀寫這兩類變量和普通函數(shù)沒什么區(qū)別厚棵。但是“ 靜態(tài)變量” 作用域在 block 之外蕉世,那Block是怎么對它進行讀寫呢?其實“靜態(tài)變量” 是通過指針傳遞婆硬,將變量傳遞到 Block 里面狠轻,所以可以修改變量值。普通的非全局變量彬犯,都是通過傳值進去Block里面向楼,當然無法修改這個變量的值查吊。

如下面的代碼

static int c = 0;//靜態(tài)變量  
  
int (^addFun)(int,int) = ^int(int a,int b){  
    c = 1;  
    return a + b + c;  
};  
NSLog(@"addValue = %d",addFun(1,2))  

還有一種方法就是通過在變量外部加上“__block”說明符,其實加了__Block之后蜜自,這個變量就變成了一個結(jié)構(gòu)體指針變量菩貌,這個原理和靜態(tài)變量一樣,由傳值方式改為指針傳遞重荠,所以就可以更改變量了箭阶。
如下所示


__block int c = 0;  
  
int (^addFun)(int,int) = ^int(int a,int b){  
    c = 1;  
    return a + b + c;  
};  
NSLog(@"addValue = %d",addFun(1,2));  

4.2、如何避免Block的循環(huán)引用

** 待補充**

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末戈鲁,一起剝皮案震驚了整個濱河市仇参,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌婆殿,老刑警劉巖诈乒,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異婆芦,居然都是意外死亡怕磨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門消约,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肠鲫,“玉大人,你說我怎么就攤上這事或粮〉妓牵” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵氯材,是天一觀的道長渣锦。 經(jīng)常有香客問我,道長氢哮,這世上最難降的妖魔是什么袋毙? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮冗尤,結(jié)果婚禮上娄猫,老公的妹妹穿的比我還像新娘。我一直安慰自己生闲,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布月幌。 她就那樣靜靜地躺著碍讯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扯躺。 梳的紋絲不亂的頭發(fā)上捉兴,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天蝎困,我揣著相機與錄音,去河邊找鬼倍啥。 笑死禾乘,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的虽缕。 我是一名探鬼主播始藕,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼氮趋!你這毒婦竟也來了伍派?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤剩胁,失蹤者是張志新(化名)和其女友劉穎诉植,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昵观,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡晾腔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了啊犬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灼擂。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖椒惨,靈堂內(nèi)的尸體忽然破棺而出缤至,到底是詐尸還是另有隱情,我是刑警寧澤康谆,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布领斥,位于F島的核電站,受9級特大地震影響沃暗,放射性物質(zhì)發(fā)生泄漏月洛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一孽锥、第九天 我趴在偏房一處隱蔽的房頂上張望嚼黔。 院中可真熱鬧,春花似錦惜辑、人聲如沸唬涧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碎节。三九已至,卻和暖如春抵卫,著一層夾襖步出監(jiān)牢的瞬間狮荔,已是汗流浹背胎撇。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留殖氏,地道東北人晚树。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像雅采,于是被迫代替她去往敵國和親爵憎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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

  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數(shù)总滩、block纲堵、GCD,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 9,816評論 10 69
  • 前言 Blocks是C語言的擴充功能闰渔,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,769評論 0 23
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,151評論 30 470
  • 在介紹Block之前通過一個簡單的應(yīng)用場景認識下Block 場景描述如下:TableView上面有多個Custom...
    黑_白_灰閱讀 1,388評論 4 29
  • 摘要 Blocks是C語言的擴充功能席函, iOS 4中引入了這個新功能“Blocks”,那么block到底是什么東西...
    CholMay閱讀 1,169評論 2 10