UI基础-图片异步下载、KVO

异步下载图片

图片下载是iOS开发中常用的功能,但系统并未提供图片下载类。
为了便于后续使用,可以将图片下载封装到一个类里面 (ImageDownloader)。
ImageDownloader 允许外界指定URL,提供开始下载和取消下载功能,并提供delegate或block将图片传递给外界。

创建ImageDownLoader类

新建工程,创建根视图控制器

// 在AppDelegate中
RootViewController *rootVC = [[RootViewController alloc] init];
    self.window.rootViewController = rootVC;
    [rootVC release];

创建ImageDownLoader类继承于NSObject

// ImageDownLoader.h中
// 创建一个协议
@protocol ImageDownLoaderDelegate <NSObject>

// 请求成功
- (void)imageDownLoadSucceedWithData:(NSData *)data;

// 请求失败
- (void)imageDownLoadFailedWithError:(NSError *)error;

@end

@interface ImageDownLoader : NSObject 

// 链接
@property (nonatomic, retain) NSMutableData *receiveData;
// data
@property (nonatomic, retain) NSURLConnection *connection;

// 声明代理对象
@property (nonatomic, assign) id<ImageDownLoaderDelegate> delegate;

// 初始化方法(需要写 请求中 可能用到的参数--网址)
- (instancetype)initWithUrl:(NSString *)url delegete:(id<ImageDownLoaderDelegate>)delegate;

// 声明开始的方法
- (void)imageDownLoadStart;
// 终止方法
- (void)imageDownLoadCancel;
// ImageDownLoader.m中
// 没有延展,可以新建一个
@interface ImageDownLoader () <NSURLConnectionDelegate, NSURLConnectionDataDelegate>

@end

@implementation ImageDownLoader

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

// 初始化
- (instancetype)initWithUrl:(NSString *)url delegete:(id<ImageDownLoaderDelegate>)delegate
{
    self = [super init];
    if (self) {
       // 创建网址对象
        NSURL *newNrl = [NSURL URLWithString:url];
        // 创建请求
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:newNrl cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:10];
        [request setHTTPMethod:@"Get"];
        // 创建链接
        self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
        // [self.connection start];
        // 设置代理
        self.delegate = delegate;
    }
    return self;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    self.receiveData = [NSMutableData data];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.receiveData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 图片请求完成
    if (_delegate != nil && [_delegate respondsToSelector:@selector(imageDownLoadSucceedWithData:)]) {
        // 代理调用协议中的方法
        [_delegate imageDownLoadSucceedWithData:self.receiveData];
    }
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    if (_delegate != nil && [_delegate respondsToSelector:@selector(imageDownLoadFailedWithError:)]) {
        [_delegate imageDownLoadFailedWithError:error];
    }
}

// 声明开始的方法
- (void)imageDownLoadStart
{
    [self.connection start];
}

// 终止方法
- (void)imageDownLoadCancel
{
    [self.connection cancel];
}

在RootViewController中调用ImageDownLoader类实现方法

@interface RootViewController () <ImageDownLoaderDelegate>

@property (nonatomic, retain) UIImageView *imageV;
@property (nonatomic, retain) ImageDownLoader *imageDL;

@end

@implementation RootViewController

- (void)dealloc
{
    // 当页面被销毁时 终止请求
    [_imageDL imageDownLoadCancel];
    [_imageDL release];
    [_imageV release];
    [super dealloc];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.imageV = [[[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];
    self.imageV.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:self.imageV];

    // 创建请求对象
    self.imageDL = [[ImageDownLoader alloc] initWithUrl:@"http://img3.douban.com/view/event_poster/median/public/10f53a2ad8b38c5.jpg" delegete:self];
    // 开始请求
    // [self.imageDL imageDownLoadStart];
    [self.imageDL release];

}

// 实现协议中的方法
- (void)imageDownLoadSucceedWithData:(NSData *)data
{
    self.imageV.image = [UIImage imageWithData:data];
    // NSLog(@"%@", data);
}

- (void)imageDownLoadFailedWithError:(NSError *)error
{
    NSLog(@"%@", error);
}

UITableView中图片的异步下载

UITableView的重用机制,让我们能用很少的cell来呈现很多的内容 (cell和model的数量不统一)。
为了能正确显示图片,Model类应该提供图片获取功能(Model通过 ImageDownloader下载图片,供cell使用)。
Model类注意事项:

1、除了包含必要的数据外,还要包含一个ImageDownloader对象。
2、包含一个image。

3、包含一个图片是否正在下载的BOOL值。(用于判断是否需要开始 下载)
Cell注意事项:
 根据Model信息,做页面显示。

KVO

KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现。

KVO触发机制:一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)

##KVO使用步骤:

1、注册观察者(为被观察者指定观察者以及被观察属性)

2、实现回调方法

3、触发回调方法(被观察属性发生更改)

4、移除观察者

实现步骤:

创建新工程,添加根视图控制器

添加一个Man类继承于NSObject,创建一个属性用于监测

@interface Man : NSObject
// 钱
@property (nonatomic, retain) NSString *money;
@end

在根视图控制器中使用KVO监测属性的变化

“`
@property (nonatomic, retain) Man *man;

@end

@implementation RootViewController

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)];
    button.frame = CGRectMake(100, 100, 150, 50);
    button.backgroundColor = [UIColor blackColor];
    [button setTitle:@”点我” forState:(UIControlStateNormal)];
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:(UIControlEventTouchUpInside)];
    [self.view addSubview:button];

    /*
    KVO 键值观察者
    观察model中某一属性 值的变化
    如果 这个属性的值发生了变化 会触发一个方法

    明确:
    1.观察者 (控制器 触发一个方法 – 改变视图的颜色)
    2.被观察者(man)
    3.观察的属性(对象中的 money这个属性)

    控制器作为观察者 去观察 model(被观察者)中的一个属性 值的变化 会触发一个方法 (改变视图的)

    观察者(C) 被观察者(Model) Model发生变化 去改变 (V)视图
    */

    // 创建一个对象
    self.man = [[Man alloc] init];
    self.man.money = @”1w”;

    // 添加一个观察者
    // 被观察者 man
    // Observer 填观察者 self
    // NSKeyValueObservingOptionNew 新值
    // NSKeyValueObservingOptionOld 旧值
    // context 携带参数
    [self.man addObserver:self forKeyPath:@”money” options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@”

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值