中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在iOS中定義和使用block

發布時間:2021-05-17 17:40:51 來源:億速云 閱讀:313 作者:Leah 欄目:移動開發

這篇文章將為大家詳細講解有關如何在iOS中定義和使用block,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

定義與使用

block 變量的聲明

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

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

block變量的賦值

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

聲明block變量的同時進行賦值

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

使用typedef定義block類型

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

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

block作為函數參數

#pragma mark block作為函數參數
 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內訪問局部變量

  • 在Block中可以訪問局部變量

  • 在聲明Block之后、調用Block之前對局部變量進行修改,在調用Block時局部變量值是修改之前的舊值

  • 在Block中不可以直接修改局部變量

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

  • 在局部變量前使用下劃線下劃線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內訪問全局變量

在聲明Block之后、調用Block之前對全局變量進行修改,在調用Block時全局變量值是修改之后的新值

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

block內訪問靜態變量

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

block 造成的循環引用問題

如果對象內部有一個Block屬性,而在Block內部又訪問了該對象,那么會造成循環引用

情況一

@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();
  
// 因為myBlock作為Person的屬性,采用copy修飾符修飾(這樣才能保證Block在堆里面,以免Block在棧中被系統釋放),所以Block會對Person對象進行一次強引用,導致循環引用無法釋放

情況二

@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對象在這里無法正常釋放,在resetBlock方法實現中,Block內部對self進行了一次強引用,導致循環引用無法釋放

解決循環引用的辦法是使用一個弱引用的指針指向該對象,然后在Block內部使用該弱引用指針來進行操作,這樣避免了Block對對象進行強引用

情況一

@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對象在這里可以正常被釋放

情況二

@interface Person : NSObject

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

- (void)resetBlock;

@end


@implementation Person

- (void)resetBlock
{
 // 這里為了通用一點,可以使用__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對象在這里可以正常被釋放

關于如何在iOS中定義和使用block就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

泗洪县| 吴川市| 正宁县| 江永县| 黔南| 衡阳县| 红原县| 靖西县| 湖北省| 太谷县| 荔浦县| 缙云县| 佛坪县| 诸暨市| 新竹市| 集贤县| 九龙县| 丹棱县| 阜宁县| 鄄城县| 改则县| 石林| 新源县| 怀来县| 大兴区| 海兴县| 枣强县| 维西| 景洪市| 山东省| 吉林省| 丹棱县| 浦东新区| 新绛县| 安宁市| 舟山市| 商南县| 保靖县| 都兰县| 固阳县| 孟津县|