block传值以及利用block封装一个网络请求类

1.block在俩个UIViewController间传值

最近刚学了几招block 的高级用法,其实就是利用block语法在俩个UIViewController之间传值,在这里分享给初学者,同时也方便我自己理解。我们知道UINavigationController类管理UIViewController的时候,利用的是“栈”的思想,在这里不做过多解释,切入正题,假设我们现在有俩个UIViewController,viewC1和viewC2,viewC1比viewC2先进入到UINavigationController里,即viewC2是由viewC1push出来的,这里的传值是指将viewC2的值传到viewC1里面。例如通讯录的修改,微信里修改信息等。

不多说,直接上例子:

一.首先在viewC2的头文件中的代码:

//1 。重定义一个block类型
typedef void(^BL)(UIColor *color);
typedef void(^stringBL)(NSString *string);
@interface SecondViewController : UIViewController
//定义一个block属性 一定要使用copy特性  原因:
@property (nonatomic, copy) BL block;
@property (nonatomic, copy) stringBL string;
- (void)valueBlock:(BL)block;
- (void)valueStringBlock:(stringBL)block;

提示:

重定义block在Xcode中有快捷实现方式,直接在@interfacexxx 上面一行打typedef会有提示: 直接回车,第一个参数是返回值类型,第二个为重定义的block名称,第三个为要传参数类型和参数名;然后需要定义重定义block类型的属性,并且实现参数为该重定义类型block的方法。

二.viewC2的.m文件中代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
    button.frame = CGRectMake(0, 70, 320, 40);
    [self.view addSubview:button];
    [button setTitle:@"return 1 page" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)buttonAction:(UIButton *)button
{
//    2.在合适的地方执行block代码
    self.block([UIColor redColor]);
    self.string(@"asdasdasd");
    [self.navigationController popToRootViewControllerAnimated:YES];
}
- (void)valueBlock:(BL)block
{
    self.block = block;
}
- (void)valueStringBlock:(stringBL)block
{
    self.string = block;
}

解释:实现头文件中定义的方法,方法内部写将参数赋值给重定义block的属性,然后在合适的地方执行block代码,block里面的参数即你要传的值。

三.在viewC1中push第二个页面的时候调用 viewC2的方法,直接回车,block重定义中的参数名里存的即是要在viewC1中修改的值。

2.利用block封装网络请求类。

1.创建网络请求类NetRequest,头文件如下

typedef void(^BLOCK)(id result);

@interface NetRequest : NSObject
@property (nonatomic, copy) BLOCK bl;
- (void)requestNetWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl;
+ (void)PostWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl;
@end

解释:该处利用的是异步post传值,头文件写法基本上跟block传值一样,我这里写了一个+号方法,为的是能在使用NetRequest类的时候更加方便。可以看到这里的方法有三个参数,分别是url的地址,以及设置request的HttpBody属性的,这里属于网络请求,不做过多解释。

2.下面看.m文件:实现俩个方法

- (void)requestNetWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl
{
    self.bl = bl;
    NSURL *url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30];
    request.HTTPMethod = @"post";
    NSData *bodyData = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = bodyData;
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
       NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options :NSJSONReadingMutableContainers error:nil];
        NSLog(@"%d", [[dic objectForKey:@"news"] count]);
        self.bl(dic);

}];

}
+ (void)PostWithUrl:(NSString *)urlStr BodyOfRequestForString:(NSString *)bodyStr block:(BLOCK)bl
{
    NetRequest *netRequest = [[NetRequest alloc] init];
    [netRequest requestNetWithUrl:urlStr BodyOfRequestForString:bodyStr block:bl];
}

解释:-方法中首先要设置属性block=参数block,再将要传的值添加到block方法的参数中。+号方法是利用-号方法将参数block传给属性block。因为在+号方法中不能直接给属性赋值。

3.如何使用:将数据传输到ViewController上

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.array = [NSMutableArray array];
        self.title = @"新闻";
        NSString *urlStr = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";
        NSString *bodyStr = @"date=20131129&startRecord=1&len=30&udid=1234567890&terminalType=Iphone&cid=213";
        [NetRequest PostWithUrl:urlStr BodyOfRequestForString:bodyStr block:^(id result) {
            self.array = [result objectForKey:@"news"];
            [self.tableView reloadData];
        }];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) style:UITableViewStylePlain];
    [self.view addSubview:self.tableView];
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"reuse"];

}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *str = @"reuse";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:str];
    cell.textLabel.numberOfLines = 2;
    cell.textLabel.text = [[self.array objectAtIndex:indexPath.row] objectForKey:@"title"];
    return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    WebViewController *webVC = [[WebViewController alloc] init];
    webVC.webUrl = [[self.array objectAtIndex:indexPath.row] objectForKey:@"newsUrl"];
    [self.navigationController pushViewController:webVC animated:YES];
    [webVC release];
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.array count];
}

下面来看看为什么我们要用这种传值方式:因为我要把当前获得的数据传输给一个UIViewController,而这个UIViewController上面有UITableView,需要刷新,而我们获取网络数据的时候使用的是利用block封装的一个获取NSData的方法,该方法会在数据加载完后才会执行块语句,而且网络会有延迟,我们的UI界面会优先于数据显示在手机上,所以当数据请求成功后,我们需要刷新页面,即调用UITableView的reloadData方法,所以才使用这种策略。

这是今天新get的技能,在这里分享给大家,我是个新手,有上面问题还望能得到大家的指导。谢谢!

block传值以及利用block封装一个网络请求类

时间: 2024-11-08 13:46:19

block传值以及利用block封装一个网络请求类的相关文章

31封装一个网络请求的服务

①创建一个服务类 @Injectable() 在服务类中定义方法.数据 sendRequest ( myUrl : string ) { return this.http.get( myUrl ).map(  (response : Response) => response.json()  ) } ②给服务指定提供商 providers : [ MyHttpService ]  模块.组件限定作用范围 ③调用服务 import { } this.myHttpService.sendRequse

iOS 自己封装的网络请求,json解析的类

基本上所有的APP都会涉及网络这块,不管是用AFNetWorking还是自己写的http请求,整个网络框架的搭建很重要. 楼主封装的网络请求类,包括自己写的http请求和AFNetWorking的请求,代码简单,主要是框架搭建.简单来说,就是一个请求类,一个解析类,还有若干数据类. 以下代码以公开的天气查询api为例: 1.网络请求类 我把常用的网络请求方法都封装好了,你只需要写自己的接口,传递apiName,params等参数就可以. #pragma mark ios请求方式 //ios自带的

ios中封装网络请求类

ios中封装网络请求类 #import "JSNetWork.h" //asiHttpRequest #import "ASIFormDataRequest.h" //xml 的解析 #import "UseXmlParser.h" //判断是否联网 #import "Reachability.h" //sbJson,判断json的解析 #import "JSON.h" @implementation JS

基于Volley,Gson封装支持JWT无状态安全验证和数据防篡改的GsonRequest网络请求类

这段时间做新的Android项目的客户端和和REST API通讯框架架构设计,使用了很多新技术,最终的方案也相当简洁优雅,客户端只需要传Java对象,服务器端返回json字符串,自动解析成Java对象, 无状态安全验证基于JWT实现,JWT规范的细节可以参考我前面的文章.JWT的token和数据防篡改签名统一放在HTTP Header中,这样就实现了对请求内容和返回结果的无侵入性,服务器端也可以在全局过滤器中统一处理安全验证. Android客户端使用了Volley网络请求框架和Gson解析库,

如何利用xib封装一个view

1.新建一个xib文件描述一个view的内部控件. 2.新建一个新的类,继承自某个系统自带的view:继承的自哪个类,取决与xib根对象的class.<新建类的类名与xib文件名保持一致> 3.将xib中的控件和自定义(第3步)的类进行连线. 4.提供类方法快速返回一个创建好的自定义view,屏蔽从xib加载的过程.

AFNetworking封装的网络请求

#import "AFNetworking.h" typedef void(^SuccessBlock)(AFHTTPRequestOperation * operation, id responseObj); typedef void(^FailBlock)(NSError * error, id responseObj); #import <Foundation/Foundation.h> @interface NetworkingManager : NSObject

自己封装的网络请求

#import <Foundation/Foundation.h> //定义枚举typedef NS_ENUM(NSInteger){    LDT_GET,    LDT_POST}URLRequestMethod; //定义返回值block网络请求结果typedef void(^ResultBlock)(NSData *data,NSURLResponse *response,NSError *error); @interface LDTNetWorkRequestManager : NS

Xamarin.Android之封装个简单的网络请求类

一.前言 回忆到上篇 <Xamarin.Android再体验之简单的登录Demo> 做登录时,用的是GET的请求,还用的是同步, 于是现在将其简单的改写,做了个简单的封装,包含基于HttpClient和HttpWebRequest两种方式的封装. 由于对这一块还不是很熟悉,所以可能不是很严谨. 二.先上封装好的代码 1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Json

利用Jackson封装常用JsonUtil工具类

在日常的项目开发中,接口与接口之间.前后端之间的数据传输一般都是使用JSON格式,那必然会封装一些常用的Json数据转化的工具类,本文讲解下如何利用Jackson封装高复用性的Json转换工具类. 转换格式属性配置 首先,我们需要对Json对象转换自定义些常用配置属性,封装成适合项目接口规则的工具类.代码如下: @Slf4j public class JsonUtil { private static ObjectMapper objectMapper = new ObjectMapper();