下面是我自己對(duì)block的理解和運(yùn)用

IOSBlock之頁(yè)面之間的傳值問(wèn)題

一.字典 數(shù)組和字符串的傳值

blcok的基本格式:返回值類(lèi)型(^block變量名)(形參列表) = ^(形參列表) {

};

調(diào)用Block保存的代碼

block變量名(實(shí)參);

默認(rèn)情況下,Block內(nèi)部不能修改外面的局部變量

Block內(nèi)部可以修改使用__block修飾的局部變量

void (^myBlock1)(void);? //無(wú)返回值,無(wú)參數(shù)

void (^myBlock2)(NSObject, int); //有返回值,有參數(shù)

NSString* (^myBlock3)(NSString* name, int age); //有返回值和參數(shù),并且在參數(shù)類(lèi)型后面加入了參數(shù)名(僅為可讀性

有參數(shù)無(wú)返回值的Block

**

*? 調(diào)用這個(gè)block進(jìn)行兩個(gè)參數(shù)相加

*

*? @param int 參數(shù)A

*? @param int 參數(shù)B

*

*? @return 無(wú)返回值

*/

void (^sumBlock)(int ,int ) = ^(int a,int b){

NSLog(@"%d + %d = %d",a,b,a+b);

};

/**

*? 調(diào)用這個(gè)sumBlock的Block,得到的結(jié)果是20

*/

sumBlock(10,10);

有參數(shù)有返回值的Block

/**

*? 有參數(shù)有返回值

*

*? @param NSString 字符串1

*? @param NSString 字符串2

*

*? @return 返回拼接好的字符串3

*/

NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){

return [NSString stringWithFormat:@"%@%@",str1,str2];

};

//調(diào)用logBlock,輸出的是 我是Block

NSLog(@"%@", logBlock(@"我是",@"Block"));

1.我發(fā)現(xiàn)字符串傳值的話(huà)比較容易但是字典傳值的時(shí)候需要將字典中的值取出來(lái)進(jìn)行傳值或者進(jìn)行字典轉(zhuǎn)模型進(jìn)行傳值也比較容易,總之來(lái)說(shuō)字符串傳值很輕松的 也解決了很多傳值的bug問(wèn)題.

其中代碼是這么實(shí)現(xiàn)的

第二個(gè)控制器的.h中寫(xiě)出代碼塊和代碼塊需要實(shí)現(xiàn)的屬性

TWOViewCtroll.h中

typedef void (^ReturnTextBlock)(NSString *showText);

@interface TWOViewCtroll : UIViewController

@property (nonatomic, copy) ReturnTextBlock returnTextBlock;

- (void)returnText:(ReturnTextBlock)block;

在.m中

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view.

//? ? lable = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];

//? ? lable.text = @"taishabi";

//? ? lable.backgroundColor = [UIColor blueColor];

//? ? lable.textColor = [UIColor blackColor];

//? ? [self.view addSubview:lable];

//? ? dic = [[NSMutableDictionary alloc] initWithObjectsAndKeys:

//? ? ? ? ? @"abc",@"name",

//? ? ? ? ? @"12",@"age",

//? ? ? ? ? @"老了",@"old"

//? ? ? ? ? , nil];

arr = [NSMutableArray arrayWithObjects:@"123",@"456",@"789",@"101112",@"131415", nil];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];

[self.view addGestureRecognizer:tap];

}

-(void)click:(UITapGestureRecognizer *)tap

{

[self dismissViewControllerAnimated:NO completion:nil];

}

- (void)returnText:(ReturnTextBlock)block {

self.returnTextBlock = block;

}

- (void)viewWillDisappear:(BOOL)animated {

if (self.returnTextBlock != nil) {

self.returnTextBlock([arr objectAtIndex:0]);

}}

在第一個(gè)界面需要代碼

ViewController.m

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

lable = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];

//? ? lable.text = @"123456789";

lable.backgroundColor = [UIColor blueColor];

lable.textColor = [UIColor blackColor];

[self.view addSubview:lable];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];

[self.view addGestureRecognizer:tap];

}

-(void)click:(UITapGestureRecognizer *)tap

{

TWOViewCtroll *two = [[TWOViewCtroll alloc] init];

[two returnText:^(NSString *showText) {

lable.text = showText;

}];

[self presentViewController:two animated:NO completion:nil];

}

2.在這段代碼中可以看出我們創(chuàng)建正常的字符串傳值的話(huà)可以很輕松的進(jìn)行傳值在字典中可以將字典的所有key值進(jìn)行便利出來(lái)for (<#type *object#> in <#collection#>) {

<#statements#>

}

在這里將所有字典key值全部取出放入字符串中便可實(shí)現(xiàn)輕松傳值,如果我們?cè)陂_(kāi)發(fā)中會(huì)遇到各種各樣的字典和json文件我們可以將json文件解析出來(lái)之后進(jìn)行modle轉(zhuǎn)模型便可實(shí)現(xiàn)輕松傳值

3.我們?cè)谶@段代碼中可以發(fā)現(xiàn)我們的數(shù)組中的值也是通過(guò)下標(biāo)進(jìn)行取出的,這個(gè)道理和字典去key值是一樣的都是將值取出來(lái)然后變成字符串屬性傳值到新的界面如果很多數(shù)據(jù)的數(shù)組我們便可以是使用for (<#type *object#> in <#collection#>) {

<#statements#>

}

來(lái)進(jìn)行遍歷了然后便可輕松地傳值到新的界面了

二.block的特性

以上便是block的簡(jiǎn)單結(jié)構(gòu)了不過(guò)blcok的結(jié)構(gòu)很多這只是其中一種

1.blcok傳值過(guò)程需要注意的是我們的傳值類(lèi)型必須和我們自己自定義的類(lèi)型一直否則系統(tǒng)將導(dǎo)致崩潰或者更加困難的傳值消失等等的bug出現(xiàn)

2.代碼塊進(jìn)行排序數(shù)組以及和函數(shù)的關(guān)系等等代碼如下

NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];

NSComparator sortBlock = ^(id string1, id string2)

{

return [string1 compare:string2];

};

NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];

NSLog(@"sortArray:%@", sortArray);

此代碼便是代碼塊進(jìn)行排序的,我們?cè)谶@里可以看出代碼塊的類(lèi)型或者屬性類(lèi)型可以使任意一中的 此處用到的便是升序和降序中的一種NSComparator然后使用新的數(shù)組將其排序后的數(shù)組進(jìn)行歸納

3.代碼塊對(duì)遞歸的調(diào)用

代碼塊想要遞歸調(diào)用,代碼塊變量必須是全局變量或者是靜態(tài)變量,這樣在程序啟動(dòng)的時(shí)候代碼塊變量就初始化了,可以遞歸調(diào)用我們可以將所有的控件或者一些文本內(nèi)容將其遍歷之后將其所有想要改變的東西進(jìn)行改變

4.在代碼塊中可以將代碼塊的屬性使用全局變量或者局部變量進(jìn)行接收從而實(shí)現(xiàn)全局屬性的擴(kuò)展

5.代碼塊的可變數(shù)據(jù)和不可變數(shù)據(jù)的結(jié)果是不同的如果是不可變得如果我們將可變數(shù)據(jù)放在block外面初始化的話(huà)他的內(nèi)容地址不會(huì)進(jìn)行改變?nèi)绻覀儗⒉豢勺償?shù)據(jù)放在外面初始化的話(huà)他的內(nèi)容就會(huì)發(fā)生變化,如果我們將可變和不可以變數(shù)據(jù)在代碼塊中初始化的話(huà)那么他們的地址將不會(huì)發(fā)生任何的變化

6.可以看出在Block內(nèi),不可變對(duì)象的值任然是初始化時(shí)的值,可變對(duì)象的值變成了新值。這是因?yàn)锽lock初始化在前,可變對(duì)象的修改在后;如果顛倒順序,先修改可變對(duì)象的值,再初始化Block,這樣Block就能同步修改后的值了。

7.代碼快傳值不會(huì)將傳進(jìn)去的值進(jìn)行改變

8.代碼塊消耗內(nèi)存比較小,傳值還是推薦代碼塊傳值因?yàn)閷?duì)內(nèi)存要求比較小

9.Block的修飾

ARC情況下

如果用copy修飾Block,該Block就會(huì)存儲(chǔ)在堆空間。則會(huì)對(duì)Block的內(nèi)部對(duì)象進(jìn)行強(qiáng)引用,導(dǎo)致循環(huán)引用。內(nèi)存無(wú)法釋放。

解決方法:

新建一個(gè)指針(__weak typeof(Target) weakTarget = Target )指向Block代碼塊里的對(duì)象,然后用weakTarget進(jìn)行操作。就可以解決循環(huán)引用問(wèn)題。

如果用weak修飾Block,該Block就會(huì)存放在棧空間。不會(huì)出現(xiàn)循環(huán)引用問(wèn)題。

MRC情況下

用copy修飾后,如果要在Block內(nèi)部使用對(duì)象,則需要進(jìn)行(__block typeof(Target) blockTarget = Target )處理。在Block里面用blockTarget進(jìn)行操作。

TWOViewCtroll *two = [[TWOViewCtroll alloc] init];

__weak typeof(TWOViewCtroll) *weakDemo = two;

[weakDemo returnText:^(NSString *showText) {

lable.text = showText;

}];

解決循環(huán)引用問(wèn)題 但還是存在風(fēng)險(xiǎn)的因?yàn)檫@時(shí)候的block沒(méi)有run這樣就會(huì)導(dǎo)致內(nèi)容改變因?yàn)閮?nèi)存對(duì)象早就被釋放了

如果blcok是常數(shù)的情況下我們需要在變量前面加上 __weak

10.Block是什么?

- 匿名函數(shù)

- 截獲自動(dòng)變量

Block語(yǔ)法。

Block類(lèi)型變量。

Block的用途。

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

- 反向傳值

- 循環(huán)引用

11.blcok和其他傳值最明顯的特點(diǎn)就是可以逆向傳值,block可以進(jìn)行多條數(shù)據(jù)同時(shí)傳遞這方便了很多程序員但是必須參數(shù)類(lèi)型和傳遞類(lèi)型一致的情況下才可以進(jìn)行多條數(shù)據(jù)同時(shí)傳遞,Block 變數(shù)儲(chǔ)存的是一個(gè)block的參考,我們使用類(lèi)似宣告指標(biāo)的方式來(lái)宣告,不同的是這時(shí)block變數(shù)指到的地方是一個(gè)函數(shù),而指標(biāo)使用的是「*」,block則是使用「^」來(lái)宣告,我們可以定義一個(gè)全域的block

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容