当前位置: 首页 > 工具软件 > iOS Block UI > 使用案例 >

iOS Block的使用

宋新知
2023-12-01

block定义

iOS4.0系统已经开始支持Block,在编程过程中,block被OC看成是对象,它封装了一段代码,这段代码可以在任何时候执行。Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或者返回值。Blcok的定义式如下:

返回值类型(也可以不返回,这是写void) (^名称)(传入的参数(一个或多个或不传))= (^传入的参数){
    //具体实现方法
}

__block

Block和传统的函数指针很类似,但是还是有所区别的:block是inline的,并且它对局部变量是只读的,可以在block块里使用局部变量,但是不能改变局部变量的值,因为在block块里使用的时候是Copy过来的,不在是原来的变量了,所以不可以对其改变值。如果要是想改变值的话可以用__block或者static定义变量,代码如下:

__block int number = 100;
void (^blockNumner)() = ^(){
     number ++;
}

block传值

Block做为property属性可以实现页面之间的传值。block传值相对代理来说要简单一些,不用声明协议,实现协议方法等等,只要创建block,传值即可使用,实现第二个界面的数据传到第一个界面上的功能,代码如下:

第一个界面

//.h
#import <UIKit/UIKit.h>
//创建block
typedef void(^blockStr)(NSString *str);
@interface FirstViewController : UIViewController
@property (nonatomic, copy)blockStr BStr;
@end


//.m

#import "FirstViewController.h"

@interface FirstViewController ()
@property (nonatomic, strong) UITextField *tf;
@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];

    _tf = [[UITextField alloc]initWithFrame:CGRectMake(20, 100, self.view.frame.size.width-40, 30)];
    //_tf.borderStyle = UIText
    _tf.layer.borderWidth = 1.0;
    _tf.layer.borderColor = [UIColor groupTableViewBackgroundColor].CGColor;
    [self.view addSubview:_tf];


    //添加手势,取消视图
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(cancel)];
    [self.view addGestureRecognizer:tap];
}
- (void)cancel
{
//当第二个界面开始消失的时候,传值
    [_tf resignFirstResponder];
    if (self.BStr) {
        self.BStr(self.tf.text);
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

第二个界面

#import "ViewController.h"
#import "FirstViewController.h"

@interface ViewController ()
@property (nonatomic, strong) UILabel *label;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _label = [[UILabel alloc]initWithFrame:CGRectMake(20, 100, self.view.frame.size.width-40, 60)];
    _label.layer.borderColor = [UIColor groupTableViewBackgroundColor].CGColor;
    _label.layer.borderWidth = 1.0;
    [_label.layer setMasksToBounds:YES];
    [_label.layer setCornerRadius:5.0];
    [self.view addSubview:_label];

    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(60, CGRectGetMaxY(_label.frame)+20, self.view.frame.size.width-120, 60)];
    [button setTitle:@"点我" forState:0];
    button.backgroundColor = [UIColor yellowColor];
    [button setTitleColor:[UIColor blackColor] forState:0];
    [button.layer setMasksToBounds:YES];
    [button.layer setCornerRadius:5.0];
    [button addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}
- (void)btnClick
{
//在点击按钮,跳转到第二个界面的按钮响应事件里实现赋值block的传值。
    FirstViewController *first = [[FirstViewController alloc]init];
    first.BStr = ^(NSString *bstr){
        self.label.text = bstr;
    };
    [self presentViewController:first animated:YES completion:nil];
}

感觉平时block用的也不是很多啊,大多都是在大牛们封装好的第三方里见过,如刷新的控件啊(MJRefresh),而且block使用最多的就是传值方面了吧。下面是我对AFNetworking的重新封装,可以一个方法做各种请求,不用再每次请求数据的时候都创建请求控制器,用的就是block的传值,代码如下:
AFNetworking3.0更新了方法,AFURLConnectionOperation,AFHTTPRequestOperation,AFHTTPRequestOperationManager这几个类已经被废弃

AFNetworkingd 重新封装

首先创建一个NSObject的类,在.h文件里写一个请求数据的方法

#import <Foundation/Foundation.h>

@interface Request : NSObject
//get请求
+ (void)requestData:(NSString *)string  widthBlcok:(void (^)(NSDictionary *dic))block ;
//post请求,拼接data
+ (void)requestData:(NSString *)string  withDicAndData:(NSDictionary *)dict widthBlcok:(void (^)(NSDictionary *dic))block ;
//post请求,不拼接data
+ + (void)requestData:(NSString *)string  withDic:(NSDictionary *)dict widthBlcok:(void (^)(NSDictionary *dic))block ;
@end

在.m文件里实现具体的请求方法,并传值。

#import "Request.h"
#import <AFNetworking.h>

@implementation Request
+ (void)requestData:(NSString *)string  widthBlcok:(void (^)(NSDictionary *dic))block
{
    AFHTTPSessionManager *request = [AFHTTPSessionManager manager];
    request.responseSerializer = [AFHTTPResponseSerializer serializer];
    //get请求

    [request GET:string parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
        NSLog(@"progress!");
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
       // NSLog(@"%@",responseObject);
         NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
        if (block) {
            block(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error:%@",error);
    }];


}
+(void)requestData:(NSString *)string withDicAndData:(NSDictionary *)dict widthBlcok:(void (^)(NSDictionary *))block
{
    //post请求,拼接data二进制流
    AFHTTPSessionManager *request = [AFHTTPSessionManager manager];
    request.responseSerializer = [AFHTTPResponseSerializer serializer];
    //post请求
    [request POST:string parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //上传图片 ,以文件流的格式
        [formData appendPartWithFileData:dict[@"data"] name:@"avatar" fileName:dict[@"fileName"] mimeType:@"image/png"];
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        NSLog(@"progress!");
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
        if (block) {
            block(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error:%@",error);
    }];

}
+ + (void)requestData:(NSString *)string  withDic:(NSDictionary *)dict widthBlcok:(void (^)(NSDictionary *dic))block 
{
  AFHTTPSessionManager *request = [AFHTTPSessionManager manager];
    request.responseSerializer = [AFHTTPResponseSerializer serializer];
//post请求,不拼接data二进制流
    [request POST:string parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        NSLog(@"progress!");
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
        if (block) {
            block(dic);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error:%@",error);
    }];
}

在需要用这些值的页面里包含创建的类的头文件,然后取出所传的值

//传不同的URL,获取不同的数据。
//get请求
[Request requestData:@"your---url" widthBlcok:^(NSDictionary *dic) {
        NSLog(@"---%@",dic);
    }];
    NSDictionary *dict = @{@"":@"",@"":@""};
    //post请求,拼接data
    [Request requestData:@"your---url" withDicAndData:dict widthBlcok:^(NSDictionary *dic) {
        NSLog(@"-----%@",dic);
    }];
    //post请求,不拼接data
    [Request requestData:@"your---url" withDic:dict widthBlcok:^(NSDictionary *dic) {
        NSLog(@"-----%@",dic);
    }];
 类似资料: