亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

iOS中block的定義和使用

發布時間:2021-08-30 21:39:26 來源:億速云 閱讀:127 作者:chen 欄目:編程語言

本篇內容介紹了“iOS中block的定義和使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

概念

代碼塊block是蘋果在iOS4開始引入的對C語言的擴展,用來實現匿名函數的特性,block是一種特殊的數據類型,其可以正常定義變量、作為參數、作為返回值,特殊地,block還可以保存一段代碼,在需要的時候調用,目前block已經廣泛應用于iOS開發中,常用于GCD、動畫、排序及各類回調

block:我們稱代碼塊,他類似一個方法。而每一個方法都是在被調用的時候從硬盤到內存,然后去執行,執行完就消失,所以,方法的內存不需要我們管理,也就是說,方法是在內存的棧區。所以,block不像OC中的類對象(在堆區),他也是在棧區的。如果我們使用block作為一個對象的屬性,我們會使用關鍵字copy修飾他,因為他在棧區,我們沒辦法控制他的消亡,當我們用copy修飾的時候,系統會把該 block的實現拷貝一份到堆區,這樣我們對應的屬性,就擁有的該block的所有權。就可以保證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");}@endPerson *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");}@endPerson *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");}@endPerson *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");}@endPerson *p = [[Person alloc] init];[p resetBlock];// Person對象在這里可以正常被釋放

“iOS中block的定義和使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

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

ios
AI

西丰县| 安塞县| 遂宁市| 巴里| 锡林浩特市| 绥宁县| 江阴市| 黔南| 昌邑市| 漯河市| 尤溪县| 常山县| 炉霍县| 台安县| 新丰县| 丰台区| 霍山县| 昌宁县| 巩留县| 襄垣县| 井冈山市| 成安县| 咸丰县| 长葛市| 武穴市| 云南省| 六盘水市| 镇沅| 米泉市| 凤山市| 台北县| 通海县| 双牌县| 富阳市| 乡宁县| 西畴县| 青州市| 望江县| 中西区| 西林县| 曲沃县|