Abstract block compared with the traditional code is lighter, the call is simple and convenient, and can return multiple parameters, the use of block can make the code more readable, and we write the callback, we can also write directly inside the function, instead of writing a callback function
Block Closure IOS Objective-c
Catalogue [-]
- Blocks syntax
- Blocks omitted sentence pattern
- Omit return value type
- Omit argument list
- Block type variable
- Simple usage
- Callback
- Pass Value
Blocks is an extension of the C language: An anonymous function with an automatic variable (local variable). With blocks, anonymous functions can be used in the source code, that is, functions without names. In our work, name occupies a large part, function name, variable name, property name, class name, frame name, etc. must have. Being able to write a function without a name is quite attractive to programmers.
Blocks syntax
The complete form of blocks is compared with the general C-language function, with two different points.
- No name of the function
- With
^
Blocks BN Paradigm
Block_literal_expression ::= ^ block_decl compound_statement_bodyblock_decl ::=block_decl ::= parameter_listblock_decl ::= type_expression
Translation into plain English is
^
返回值类型
(参数列表)
表达式
1. 返回值类型
return value types in the same OC/C syntax
2. The parameter 参数列表
list in the same C syntax, the parameters in OC are passed through, and the syntax here is more like the list of parameters contained in the C language ().
3. 表达式
expressions allowed in the same OC/C syntax
Such as
^int (int count){ return count++; }^NSString * (NSNumber *num){ return [NSString stringWithFormat:@"%@",num]; };
People may wonder why it's Blocks
not always the case, because blocks can omit several items
Blocks omitted sentence omitting return value type
Such as:
^
return value type (参数列表)
表达式
You can 返回值类型
omit the
The above code example can be written as
^(int count){ return count++; }^(NSNumber *num){ return [NSString stringWithFormat:@"%@",num]; };
So, it seems to be more familiar.
When you omit a return value type, if there is a return statement in the expression that uses the type of the return value, if there is no return statement in the expression, use the void
type, as shown in the following code example.
The complete definition sentence is given below (using the omitted return value type sentence)
^(int count){return count+1 ;}; ^(NSNumber *num){ return [NSString stringWithFormat:@"%@",num]; }; ^(NSNumber *count){ NSLog(@"无返回类型Block count = %@", count); }; ^(void){ NSLog(@"无返回类型也无参数 Block"); };
Omit argument list
If parameters are not used, the argument list can also be omitted
^
return value type (parameter list)表达式
If there is no return value type above, the block with no parameters is also simplified to
^{
Block type variable
The block described above is the same as the C/OC definition in syntax format, except for the absence of a name and a carry ^
.
In block syntax, the block syntax can be assigned to variables declared as block types. That is, once the block syntax is used in the source code, it is equivalent to generating a value that can be assigned to the block type variable. The value generated by the block syntax in Blocks is also known as "block".
An example of declaring a Block type variable is as follows:
int (^counts)(int);
The Block type variable has no difference from other C/OC variables and can be used for the following purposes
- Automatic variables
- function parameters
- static variables
- Static global variables
- Global variables
Let's try to assign a block to the block type variable using the block syntax
int (^counts)(int) = ^(int count){return count+1 ;}; NSString *(^str)(NSNumber *num) = ^NSString *(NSNumber *num){ return [NSString stringWithFormat:@"%@",num]; };void (^blank)(NSNumber *count) = ^(NSNumber *count){ NSLog(@"无返回类型Block count = %@", count); }; void (^blank)(void) = ^(void){ NSLog(@"无返回类型也无参数 Block"); };
Use the block type variable in the function argument to pass the block to the function, and Block
the variable as the function's formal parameter
void func(int (^counts)(int)){}
When the Block is used as a type variable parameter, the description method and its complexity, such as the above parameter, can be used to simplify the description, as is the case with the function pointer type typedef
.
typedef int (^count) (int);
Override the method above
void func(count num){}
This is the C
wording of the language, replaced by the OC
wording, so that everyone more clear, in the definition of the same use
/** * 原来的写法 */-(void)funcWithCount:(int (^)(int))count{}/** * 使用typedef之后的写法 */-(void)funcWithCount:(count )count{}
Simple usage
Once you have defined block blocks of code, you can use a whole block of code as a variable, either as a local variable or as a global variable, which I think is the most convenient place to block.
Suppose you want to generate two arrays, one with 5 random numbers, one with 10 random numbers, and a method that generates a random number as a closure, which can be accessed directly later, as
NSNumber *(^randArray)(void) = ^{ int rand = arc4random() % 100; NSNumber *number = [NSNumber numberWithInt:rand]; return number; }; NSMutableArray *array1 = [[NSMutableArray alloc] init]; NSMutableArray *array2 = [[NSMutableArray alloc] init]; for (NSInteger index = 0; index<10; index++) { [array1 addObject:randArray()]; } for (NSInteger index = 0; index<5; index++) { [array2 addObject:randArray()]; }
Callback
Here is an example of a tableViewCell
button event callback, which is a headache for many people, the block can be easily implemented, and the level is very clear.
The custom cell is named blockCell
, a control is placed on the cell, and we want the switch to be in the state of the switch
switch when clicked viewController
and get the Click event.
In the blockCell.h
definition of aBlock
typedef void(^switchAction)(blockCell *);@property (nonatomic,copy)switchAction action;
Called in a switch's click-time EventswitchAction
blockCell.m
- (IBAction)switchToggle:(id)sender { self.action(self);}
The viewController
table is initialized with this custom cell in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *cellID = @"blockCell"; blockCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; cell.action = ^(blockCell *cell){ // 既可取到行,也可取到switch状态 NSLog(@"行数:%ld, switch state: %u", (long)indexPath.row, cell.switchBtn.on); }; return cell; }
Pass Value
Now a lot of popular third-party libraries have changed the callback to block, before using the delegate particularly handy have wood, are packaged well directly call to get the results I want, OK, all changed to block, do not know how to pick up the return value of block, can only be rewritten again and generally.
In fact, to encapsulate is very easy, the third-party library to return the block, a block to catch and then return to call the page on it, this would like to introduce
AFNetworing
After this, but I looked down, github
on their homepage, the readme written super clear details, want to know the children's shoes please carefully look at theirreadMe
How to add
GitHub Address: https://github.com/AFNetworking/AFNetworking
The class library can be copied to the project directory to add, recommended for cocoapods
installation, easy to update, and do not have to manually import the framework, one-click Settings
Packaging
Objective: To call the corresponding method to get the network return value directly after passing the parameter
Create a new class WebRequest
, here to write an example, you reference
#import <Foundation/Foundation.h>#import "AFNetworking.h"@interface WebRequest : NSObject-(void)requestNameWithID:(NSString *)ID WithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject, NSDictionary *myData))success failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;@end
@implementation WebRequest-(void)requestNameWithID:(NSString *)ID WithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject, NSDictionary *myData))succes failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { NSURL *url = [NSURL URLWithString:@"用ID拼接地接口地址"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { NSDictionary *dic = responseObject[@"someKey"]; success(operation, responseObject, dic);// 此处将网络返回值传递给我们自己定义的Block中的三个返回值,dic可以自定义,也可不加,如此可以返回经自己在这里已经处理好的对象,而不必调用一次,处理一次 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { failure(operation,error);// 与方法定义中的Block一致 }];}@end
Call
WebRequest *request = [[WebRequest alloc] init];[request requestNameWithID:@"123" WithSuccess:^(AFHTTPRequestOperation *operation, id responseObject, NSDictionary *myData) { // 在网络成功时在这里就可以得到返回值了,operation,responseObject,myData} failure:^(AFHTTPRequestOperation *operation, NSError *error) { // 网络失败回调}];
Sample Project Download
Fang Tsai said:
Now more and more libraries use block, ^
as Block
a sign, at first glance will be very uncomfortable, and in the unused situation will have a resistance to psychological
IOS8 also has a lot of block operation, Block has been more than two years, is the heyday, replaced delegate
also not far, I believe that we will be a little bit to explore the use of love it, I wish you good luck!
A bit too long, novice look at the circle, will write in subsequent articles about the Block object advanced usage, basic usage after reading this article can be very handy
Teach you to love blocks (closures)