码迷,mamicode.com
首页 > 移动开发 > 详细

iOS开发之Block实现同异步加载

时间:2015-08-31 19:42:45      阅读:393      评论:0      收藏:0      [点我收藏+]

标签:ios开发   异步   网络   同步   

一. 相关知识

1.控制层

负责数据的交互.控制层请求数据,会创建一个具有网络请求的对象.对象中有一个block,block会将请求到的数据回调给控制层.

2.数据的传输过程

Request(请求到数据后) 回调给Controller


二. 数据同步加载

思想:

Request对象负责下载网络数据.Controller中需要下载的数据,但直接在Controller中实现下载功能,不是一种好的习惯.采取在Request中实现下载功能,同时设置block属性,将下载数据回调给Controller(前提是Controller中实现了block).在Controller中定义一个Request对象,负责下载数据.数据下载后,会执行block,而block是在Controller中实现的,故下载数据可以Controller中使用.

<span style="font-size:18px;">Request.h //数据请求 负责加载数据 通过block将加载信息回调给Controller</span>
<span style="font-size:18px;">#import <Foundation/Foundation.h>

@interface Request : NSObject
//data负责存储请求的数据 error 负责存储操作失误的信息 目的 功能设计的用户友好
//功能失败时给用户提供失败信息
@property (nonatomic, copy) void(^block)(NSData * data, NSError * error);
//网络下载方法
- (void)requestDataFromUrl:(NSString *) url;

@end
</span>

<span style="font-size:18px;">Requset.m</span>
<span style="font-size:18px;">#import "Request.h"

@implementation Request
@synthesize block = _block;

- (void)dealloc
{
    [_block release];
    [super dealloc];
}

- (void)requestDataFromUrl:(NSString *)url {
    //网络地址
    NSURL * URL = [NSURL URLWithString:url];
    
    //通过网络地址下载数据
    NSData * data = [NSData dataWithContentsOfURL:URL];
    
    //通过block将数据返回
    @try {
        //正常的数据请求
        //1.请求的数据不为空
        //2.请求的本身就是空的
        if (nil != data) {
            //通过调用block 将数据正常返回
            self.block(data, nil);
        } else  {
            //给予数据为空的提示
            NSError * error = [[NSError alloc] initWithDomain:@"请求到得数据为空" code:404 userInfo:nil];
            
            self.block(nil, error);
            
            [error autorelease];
        }
        
    }
    @catch (NSException *exception) {
        //网络请求失败时
        //exception 抛出异常 当网络请求本身就不成功时 里面包含了操作失败
        
        NSError * error = (NSError *)exception;
        
        self.block(nil, error);
    }
}

@end
</span>

<span style="font-size:18px;">Controller.h</span>
<span style="font-size:18px;">#import "Controlller.h"
#import "Request.h"

@implementation Controlller {
    
    Request * _request;
}

- (void)viewDidLoadWithURL:(NSString *)url {
    
    //给网络属性赋值
    _request = [[Request alloc] init];
    
    //做好回调数据的接受准备
    //1.创建block 2.让request block指向创建的block
    
    _request.block = ^(NSData * data, NSError * error) {
        
        if (nil != data) {
            NSString * str = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
            NSLog(@"%@", str);
            [str release];
        } else {
            NSLog(@"%@", error.localizedDescription);
        }
    };

    [_request requestDataFromUrl:url];
}

- (void)dealloc
{
    [_request release];
    [super dealloc];
}
@end

</span>
<span style="font-size:18px;">Controller.m</span>
<span style="font-size:18px;">#import "Controlller.h"
#import "Request.h"

@implementation Controlller {
    
    Request * _request;
}

- (void)viewDidLoadWithURL:(NSString *)url {
    
    //给网络属性赋值
    _request = [[Request alloc] init];
    
    //做好回调数据的接受准备
    //1.创建block 2.让request block指向创建的block
    
    _request.block = ^(NSData * data, NSError * error) {
        
        if (nil != data) {
            NSString * str = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];
            NSLog(@"%@", str);
            [str release];
        } else {
            NSLog(@"%@", error.localizedDescription);
        }
    };

    [_request requestDataFromUrl:url];
}

- (void)dealloc
{
    [_request release];
    [super dealloc];
}
@end</span>

<span style="font-size:18px;">主函数</span>
<span style="font-size:18px;">#import <Foundation/Foundation.h>
#import "Controlller.h"
#define URL @"http://Mrshang110.local/Demo/1.txt"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //创建对象
        Controlller * ctr = [[Controlller alloc] init];
        
        //调用接口
        [ctr viewDidLoadWithURL:URL];
        
        [ctr release];
    }
    return 0;
}
</span>

三. 异步加载

<span style="font-size:18px;">#import <Foundation/Foundation.h>
#import "Controller.h"
#define URL @"http://Mrshang110.local/Demo/1.txt"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        Controller * ctr = [[Controller alloc] init];
        [ctr viewDidLoadWithUrl:URL];
        [ctr release];
        
        sleep(1);
    }
    return 0;
}

#import <Foundation/Foundation.h>

@interface Controller : NSObject

- (void)viewDidLoadWithUrl:(NSString *)url;

@end

#import "Controller.h"
#import "Request.h"

@implementation Controller {
    Request *  _request;
}


- (void)viewDidLoadWithUrl:(NSString *)url {
    
    if (nil == _request) {
        _request = [[Request alloc] init];
    }
    
    _request.block = ^(NSData * data, NSError * error) {
        
        if (nil != data) {
            NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"%@", str);
            [str release];
        } else {
            NSLog(@"%@", error.localizedDescription);
        }
    };
    
    [_request requestDataWithUrl:url];
}

- (void)dealloc
{
    [_request release];
    [super dealloc];
}

@end

#import <Foundation/Foundation.h>

@interface Request : NSObject

@property (nonatomic,copy) void(^block)(NSData * data, NSError * error);
//声明一个方法用于数据下载
- (void)requestDataWithUrl:(NSString *)url;
@end

#import "Request.h"

@implementation Request
@synthesize  block = _block;

- (void)requestDataWithUrl:(NSString *)url {
    
    NSURL * URL = [NSURL URLWithString:url];
    //创建分线程去请求数据 数据请求完回到主线程
    //NSThread 线程类 其对象是一个分线程 分线程可以从主线程独立出来 将结果通知主线程
    //主线程 和 分线程同时执行
    NSThread * thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:URL];
    //download 是一个带参数的方法 其网络请求下固定为URL
    //创建分线程thread 去执行当前类的对象方法download
    //目的 分线程中下载数据
    
    
    /*
     启
     动
     分
     线
     程
     */
    
    [thread start];
}

- (void)download:(NSURL *)url {
    //分线程需要执行的代码
    
    //创建NSData 存储下载数
    NSData * data = [NSData dataWithContentsOfURL:url];
    
    //处理请求到的数据
    @try {
        //正常的数据返回
        if (nil != data) {
            self.block(data, nil);
        } else {
            NSError * error = [[NSError alloc] initWithDomain:@"请求数据为空" code:404 userInfo:nil];
            self.block(nil, error);
        }
    }
    @catch (NSException *exception) {
        //网络请求本身错误时
        NSError * error = (NSError *)exception;
        self.block(nil, error);
    }
}

- (void)dealloc
{
    [_block release];
    [super dealloc];
}

@end</span>



版权声明:本文为博主原创文章,未经博主允许不得转载。

iOS开发之Block实现同异步加载

标签:ios开发   异步   网络   同步   

原文地址:http://blog.csdn.net/mrshang110/article/details/48133505

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!