block定義
block類似于c語言中的函數指針,其定義方式為:
返回值類型 (blockName)(參數列表)=(參數){... ...};
如:
NSString *rank = @"111";
NSString *name = @"aaa";
NSString * (^blockAppendingString)(NSString *str1, NSString *str2) = ^(NSString *str1, NSString *str2){
str1 = [str1 stringByAppendingString:str2];
return str1;
};
NSString * result = blockAppendingString(rank, name);
NSLog(@"result is :%@",result);
使用
定義好的block可以想函數一樣適用。但是更經常的是直接使用代碼塊如:
NSArray *array = [NSArray arrayWithObjects:@"3", @"2", @"1", nil];
NSArray *array2 = [array sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
return [obj1 compare: obj2];
}];
NSLog(@"array2:%@", array2);
sortedArrayUsingComparator:方法中的block被當作參數傳入方法中,并在需要的時候調用。
使用typedef
使用typedef可以定義一個代碼塊變量,當出現大量形式相同的代碼塊時,可以使用此方法:
typedef NSString * (^str_block_type)(NSString *str);
str_block_type my_block = ^(void){
return str;
};
str_block_type your_block =^(NSString *str){
return @"your block type";
};
其中str_block_type可以像int,NSString等字段一樣使用,用來定義具有相同參數列表,和返回值的block。
block參數
block可以訪問與其同級的變量,但是不能修改,如果要修改,需要將該變量定義為__block屬性的變量:
NSString *rank = @"111";
NSString *name = @"aaa";
__block NSString *result = @"22222";
NSString * (^blockAppendingString)(NSString *str1, NSString *str2) = ^(NSString *str1, NSString *str2){
result = [str1 stringByAppendingString:str2];
return result;
};
以上代碼中,result被代碼塊使用時修改了其值,因此需要定義為__block屬性,否則會報錯。
錯誤.png
值得注意的是,代碼塊在被創建時,會捕捉此時的本地變量狀態,在此之后更改變量,也不會改變block中該變量的值如:
NSString *test = @"before";
NSString * (^blockAppendingString)(NSString *str1, NSString *str2) = ^(NSString *str1, NSString *str2){
result = [str1 stringByAppendingString:str2];
NSLog(@"test:%@",test);
return result;
};
test = @"after";
blockAppendingString(rank, name);
輸出結果為“before”,而不是“after”。