欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS中block的定義與使用

 更新時(shí)間:2019年03月23日 10:40:40   作者:東升  
蘋果官方文檔聲明,block是objc對(duì)象。下面這篇文章主要給大家介紹了關(guān)于iOS中block的定義與使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

概念

代碼塊block是蘋果在iOS4開始引入的對(duì)C語言的擴(kuò)展,用來實(shí)現(xiàn)匿名函數(shù)的特性,block是一種特殊的數(shù)據(jù)類型,其可以正常定義變量、作為參數(shù)、作為返回值,特殊地,block還可以保存一段代碼,在需要的時(shí)候調(diào)用,目前block已經(jīng)廣泛應(yīng)用于iOS開發(fā)中,常用于GCD、動(dòng)畫、排序及各類回調(diào)

block:我們稱代碼塊,他類似一個(gè)方法。而每一個(gè)方法都是在被調(diào)用的時(shí)候從硬盤到內(nèi)存,然后去執(zhí)行,執(zhí)行完就消失,所以,方法的內(nèi)存不需要我們管理,也就是說,方法是在內(nèi)存的棧區(qū)。所以,block不像OC中的類對(duì)象(在堆區(qū)),他也是在棧區(qū)的。如果我們使用block作為一個(gè)對(duì)象的屬性,我們會(huì)使用關(guān)鍵字copy修飾他,因?yàn)樗跅^(qū),我們沒辦法控制他的消亡,當(dāng)我們用copy修飾的時(shí)候,系統(tǒng)會(huì)把該 block的實(shí)現(xiàn)拷貝一份到堆區(qū),這樣我們對(duì)應(yīng)的屬性,就擁有的該block的所有權(quán)。就可以保證block代碼塊不會(huì)提前消亡。

定義與使用

block 變量的聲明

block 變量的聲明格式:返回值類型(^block名字)(參數(shù)列表);

block 變量的聲明格式:返回值類型(^block名字)(參數(shù)列表);
 //聲明一個(gè)無返回值,兩個(gè)參數(shù)的 block
 void(^block1)(NSString *a,NSString *b);
 //省略寫法
 void(^block2)(NSString *,NSString *);

block變量的賦值

 //block變量的賦值
 //block變量名 = ^(參數(shù)列表){函數(shù)體};
 block1 = ^(NSString *x,NSString *y){
 NSLog(@"%@--%@",x,y);
 };
 block1(@"123123",@"QWEQWEQWE");

聲明block變量的同時(shí)進(jìn)行賦值

 //聲明 block 變量的同時(shí)進(jìn)行賦值
 int(^block3)(int) = ^(int a){
 return a*3;
 };
 NSLog(@"%d",block3(3));

使用typedef定義block類型

在實(shí)際使用Block的過程中,我們可能需要重復(fù)地聲明多個(gè)相同返回值相同參數(shù)列表的Block變量,如果總是重復(fù)地編寫一長串代碼來聲明變量會(huì)非常繁瑣,所以我們可以使用typedef來定義Block類型

#pragma mark 使用 typedef 定義 block 類型
 //定義一個(gè)無返回值類型 無參數(shù)列表的 block
 typedef void (^Block4)();
 Block4 block4 = ^(){
  NSLog(@"i am block4");
 };
 block4();

block作為函數(shù)參數(shù)

#pragma mark block作為函數(shù)參數(shù)
 int(^block5)(int,int) = ^(int a,int b){
  return a+b;
 };
 [self useBlock5:block5];
 
 //簡化書寫
 //typedef int (^Block6)(int,int);(全局聲明)
 Block6 block6 = ^(int a,int b){
  return a+b;
 };
 [self useBlock6:block6];
 
 
- (void)useBlock5:(int(^)(int,int))block5 {
 NSLog(@"block5:%d",block5(3,5));
}
- (void)useBlock6:(Block6 )block6{
 NSLog(@"block6:%d",block6(4,5));
}

block內(nèi)訪問局部變量

  • 在Block中可以訪問局部變量
  • 在聲明Block之后、調(diào)用Block之前對(duì)局部變量進(jìn)行修改,在調(diào)用Block時(shí)局部變量值是修改之前的舊值
  • 在Block中不可以直接修改局部變量
#pragma mark block -----------訪問局部變量
 //block 中不可以直接修改局部變量
 int value1 = 100;
 void (^block7)(void) = ^(){
   NSLog(@"value1:%d",value1);
 };
 value1 = 200;
 block7();//輸出100 
  • 在局部變量前使用下劃線下劃線block修飾,在聲明Block之后、調(diào)用Block之前對(duì)局部變量進(jìn)行修改,在調(diào)用Block時(shí)局部變量值是修改之后的新值
  • 在局部變量前使用下劃線下劃線block修飾,在Block中可以直接修改局部變量
#pragma mark block -----------訪問局部變量
 //block 中不可以直接修改局部變量
 //在局部變量前使用__block修飾,在Block中可以直接修改局部變量
 __block int value1 = 100;
 void (^block7)(void) = ^(){
   value1++;
  NSLog(@"value1:%d",value1);
 };
 value1 = 200;
 block7();//輸出100 __block 修飾之后輸出200

block內(nèi)訪問全局變量

在聲明Block之后、調(diào)用Block之前對(duì)全局變量進(jìn)行修改,在調(diào)用Block時(shí)全局變量值是修改之后的新值

#pragma mark ------------------block 訪問全局變量
 //在Block中可以訪問全局變量
 value2 = 100;
 void(^block8)(void) = ^(){
  //在Block中可以直接修改全局變量
  self->value2++;
  NSLog(@"value2:%d",self->value2);
 };
 value2 = 200;
 block8();

block內(nèi)訪問靜態(tài)變量

#pragma mark --------block內(nèi)訪問靜態(tài)變量
 static int value3 = 100;
 void(^block9)(void) = ^(){
  value3++;//在Block中可以直接修改靜態(tài)變量
  NSLog(@"value3:%d",value3);
 };
 //在聲明Block之后、調(diào)用Block之前對(duì)靜態(tài)變量進(jìn)行修改,在調(diào)用Block時(shí)靜態(tài)變量值是修改之后的新值
 value3 = 200;
 block9();

block 造成的循環(huán)引用問題

如果對(duì)象內(nèi)部有一個(gè)Block屬性,而在Block內(nèi)部又訪問了該對(duì)象,那么會(huì)造成循環(huán)引用

情況一

@interface Person : NSObject

@property (nonatomic, copy) void(^myBlock)();

@end


@implementation Person

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

@end


Person *p = [[Person alloc] init];
  
p.myBlock = ^{
 NSLog(@"------%@", p);
};
p.myBlock();
  
// 因?yàn)閙yBlock作為Person的屬性,采用copy修飾符修飾(這樣才能保證Block在堆里面,以免Block在棧中被系統(tǒng)釋放),所以Block會(huì)對(duì)Person對(duì)象進(jìn)行一次強(qiáng)引用,導(dǎo)致循環(huán)引用無法釋放

情況二

@interface Person : NSObject

@property (nonatomic, copy) void(^myBlock)();

- (void)resetBlock;

@end


@implementation Person

- (void)resetBlock
{
 self.myBlock = ^{
  NSLog(@"------%@", self);
 };
}

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

@end


Person *p = [[Person alloc] init];
[p resetBlock];

// Person對(duì)象在這里無法正常釋放,在resetBlock方法實(shí)現(xiàn)中,Block內(nèi)部對(duì)self進(jìn)行了一次強(qiáng)引用,導(dǎo)致循環(huán)引用無法釋放

解決循環(huán)引用的辦法是使用一個(gè)弱引用的指針指向該對(duì)象,然后在Block內(nèi)部使用該弱引用指針來進(jìn)行操作,這樣避免了Block對(duì)對(duì)象進(jìn)行強(qiáng)引用

情況一

@interface Person : NSObject

@property (nonatomic, copy) void(^myBlock)();

@end


@implementation Person

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

@end


Person *p = [[Person alloc] init];
__weak typeof(p) weakP = p;

p.myBlock = ^{
 NSLog(@"------%@", weakP);
};
p.myBlock();
  
// Person對(duì)象在這里可以正常被釋放

情況二

@interface Person : NSObject

@property (nonatomic, copy) void(^myBlock)();

- (void)resetBlock;

@end


@implementation Person

- (void)resetBlock
{
 // 這里為了通用一點(diǎn),可以使用__weak typeof(self) weakP = self;
 __weak Person *weakP = self;
 self.myBlock = ^{
  NSLog(@"------%@", weakP);
 };
}

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

@end


Person *p = [[Person alloc] init];
[p resetBlock];

// Person對(duì)象在這里可以正常被釋放

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • iOS中關(guān)于Taptic-Engine震動(dòng)反饋的深入解析

    iOS中關(guān)于Taptic-Engine震動(dòng)反饋的深入解析

    這篇文章主要給大家介紹了關(guān)于iOS中關(guān)于Taptic-Engine震動(dòng)反饋的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • iOS實(shí)現(xiàn)卡片堆疊效果

    iOS實(shí)現(xiàn)卡片堆疊效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)卡片堆疊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • iOS開發(fā)使用UITableView制作N級(jí)下拉菜單的示例

    iOS開發(fā)使用UITableView制作N級(jí)下拉菜單的示例

    這篇文章主要介紹了iOS開發(fā)使用UITableView制作N級(jí)下拉菜單的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • iOS10 App適配權(quán)限 Push Notifications 字體Frame 遇到的問題

    iOS10 App適配權(quán)限 Push Notifications 字體Frame 遇到的問題

    這篇文章主要介紹了iOS10 App適配權(quán)限 Push Notifications 字體Frame 遇到的問題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • iOS Runtime詳解(新手也看得懂)

    iOS Runtime詳解(新手也看得懂)

    這篇文章主要給大家介紹了關(guān)于iOS Runtime的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Objective-C中關(guān)于實(shí)例所占內(nèi)存的大小詳解

    Objective-C中關(guān)于實(shí)例所占內(nèi)存的大小詳解

    這篇文章主要給大家介紹了關(guān)于Objective-C中實(shí)例所占內(nèi)存的大小的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-05-05
  • iOS客戶端本地推送實(shí)現(xiàn)代碼

    iOS客戶端本地推送實(shí)現(xiàn)代碼

    這篇文章主要介紹了iOS客戶端本地推送實(shí)現(xiàn)代碼,并確定程序中只有一個(gè)彈出框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • iOS實(shí)現(xiàn)聊天輸入框功能

    iOS實(shí)現(xiàn)聊天輸入框功能

    大家都經(jīng)常使用微信聊天功能,在沒事的時(shí)候就會(huì)想微信聊天輸入框的實(shí)現(xiàn)過程,很無聊吧。今天小編抽空給大家分享iOS實(shí)現(xiàn)聊天輸入框功能,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-02-02
  • iOS實(shí)現(xiàn)微信搖一搖功能

    iOS實(shí)現(xiàn)微信搖一搖功能

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)微信搖一搖功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • iOS實(shí)現(xiàn)支付寶螞蟻森林隨機(jī)按鈕及抖動(dòng)效果

    iOS實(shí)現(xiàn)支付寶螞蟻森林隨機(jī)按鈕及抖動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)支付寶螞蟻森林隨機(jī)按鈕及抖動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評(píng)論