代理模式以及多线程的简单使用

什么是代理?

Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

意译一下就是:代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另外一个对象和程序中其他的对象进行交互。 主对象(这里指的是delegating object)中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一个事件。这个代理可以通过更新自己或是其它对象的UI界面或是其它状态来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其它即将发生的事件该如何来处理。代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。

我在很久之前就学习过代理模式,但是因为用的不多所以经常忘记,因为要工作了我想肯定会经常用代理模式,所以想重新将它捋一下.

在正式开始之前介绍一下这个小demo,整体是一个navigationController,一共有两个VC.第一页创建了一个imageView和跳转到第二页的Btn.第二页只有一个跳转回第一页的Btn,点击这个btn从网页上下载一个图片,然后加载到第一页的imageView上.再跳转回第一页

第一步

在VC2中声明一个delegate协议.协议里是你想要实现的函数,默认是必选的函数.可以在前面加上@optional(可选)

@protocol imageRead <NSObject>

-(void)changeDownloadedImage:(UIImage *)image;

@end

第二步

在VC2.h的声明中创建一个delegate属性变量.属性为nonatomic,assign.在非ARC下是assign,arc下用weak好了。指针就不会释放的。

@property (nonatomic, assign) id <imageRead> delegate;

第三步

在VC2.m中点击返回按钮的函数中实现delegate发送消息

[self.delegate changeDownloadedImage:image];

第四步

回到VC1.h中声明协议为协议.

实现代理函数

-(void)changeDownloadedImage:(UIImage *)image{
        [_imageView setImage:image];
}

第五步

在VC1.m中跳转到第二页的时候,设置第二页的代理为第一页:

-(void)clickBtn:(UIButton *)sender{
    ViewController1 *vc2 = [[ViewController1 alloc] init];
    vc2.delegate = self;
    [self.navigationController pushViewController:vc2 animated:YES];
}

这五步步骤不必相同,但是缺一不可,源码在我的资源里,有需要的同学可以拿来看看.

在从网上获取图片时,我第一次用的是AFNetworking框架中的UIKit+UIImageView中的方法:

- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest

placeholderImage:(UIImage *)placeholderImage

success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success

failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure

AFN使用的是多线程的方法,这个库写的确实很干净简洁,在这个函数中先从cache加载url图,若没有缓存,先用placeholder图替代.

于是我就想不用AFN从网上获取,

       UIImage *result;
        NSData *date = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img05.tooopen.com/images/20150422/tooopen_sy_119846376592.jpg"]];
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        path = [path stringByAppendingString:@"userInfo"];
        [date writeToFile:path atomically:YES];
        result = [UIImage imageWithData:date];

        [self.delegate changeDownloadedImage:image];
        [self.navigationController popViewControllerAnimated:YES];

问题就来了…反面案例:在返回第一页的时候UI会被阻塞,因为dataWithContentsOfURL:方法在下载的时候时间可能会有点长,就像之前翻译的那篇多线程文章说的,这个时候就想到了多线程.把它开辟一个后台队列扔到队列去下载,下载完了通过delegate协议将image传回去:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        UIImage *result;
        NSData *date = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://img05.tooopen.com/images/20150422/tooopen_sy_119846376592.jpg"]];
        NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
        path = [path stringByAppendingString:@"userInfo"];
        [date writeToFile:path atomically:YES];
        result = [UIImage imageWithData:date];
        [self.delegate changeDownloadedImage:result];
    });
    [self.navigationController popViewControllerAnimated:YES];

这次就好了,在点击的时候UI不会卡住,而是先跳转回第一页,在image下载完之后会被协议加载出来.

时间: 2024-10-13 19:02:05

代理模式以及多线程的简单使用的相关文章

深刻理解代理模式在java中如何优化系统性能

最近参与实习公司的项目迭代,项目中需要实现系统的快速响应和大量数据处理.在不断的学习中获得一点儿心得,先记录下来.慢慢的修改! 关于代理模式的知识和简单应用之前的学习笔记中已经有记录了,可以复习一下.这里主要记录如何使用代理模式来实现延迟加载,进而提升系统系能和反应速度. 使用代理模式实现延迟加载的一个简单实例: 需求:项目中对系统的启动速度做了一定的要求 我们在系统首次加载时,因为不需要实际的数据来构造显示界面,这就为我们实现系统首次加载的快速响应提供了可能.在常规模式下,我们一般会在系统启动

java代理模式之静态代理

作为一个初级开发者,可能不会接触到代理模式,但是在很多框架的使用中都不知不觉使用了代理模式,比如servlet的过滤器链,spring的AOP,以及spring mvc的拦截器等.所以了解代理模式对于个人的成长是不可避免的. 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为"代理"的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务. 原文和作者一起讨论:http:

Java程序性能优化之代理模式

代理模式的用处很多,有的是为了系统安全,有的是为了远程调用,这里我们,主要探讨下由于程序性能优化的延迟加载. 首先我们来看下代理模式设计 先首先简单阐述下什么叫代理模式吧 代理设计模式有一个接口,另外还有真实主题类和代理类,真实类和代理类都实现了接口,代理类和真实主题类是关联和聚合关系.客户端与接口关联. 代理分为静态代理和动代态代理所谓静态代理是为真实主题手动创建一个代理,而动态代理则是jvm在运行时运用字节码加载技术自动创建一个代理,并不用关心接口和真是主题类 具体如何实现 哦,对了差点忘了

C#设计模式之代理模式(一)

原文地址:http://blog.csdn.net/lovelion/article/details/8227953 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口.根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理.远程代理.虚拟代理.缓冲代理等,它们应用于不同的场合,满足用户的不同需求. 15.1 代理模式概述 近年来,代购已逐步成为电

8、[C++]代理模式

代理模式 代理模式: 为其他对象提供一种代理以控制对这个对象的访问. 情景: 1. 有人找公司老总, 但是老总很忙, 于是要找就先找老总的助理, 助理等老总不忙时, 再来告诉老总吧. 2. 想象一下古代大户人家的大小姐与仆人偷情, 有一天仆人想约大小姐出来赏月, 但仆人可能不方便直接见大小姐,  于是先告诉大小姐的丫鬟, 由丫鬟转告大小姐. 上面这两个情景, 助理和丫鬟都是担当着代理的这个角色(为其他对象提供一种代理以控制对这个对象的访问, 这里指老总和小姐). Subject: 抽象类, 定义

Java设计模式9:代理模式

代理模式 代理模式的定义很简单:给某一对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结构 有些情况下,一个客户不想活着不能够直接引用一个对象,可以通过代理对象在客户端和目标对象之间起到中介作用.代理模式中的角色有: 1.抽象对象角色 声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象 2.目标对象角色 定义了代理对象所代表的目标对象 3.代理对象角色 代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象:代理对象提供一个与目标

深入浅出设计模式——代理模式(Proxy Pattern)

模式动机在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务.通过引入一个新的对象(如小图片和远程代理对象)来实现对真实对象的操作或者将新的对象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一个对象,这就是代理模式的模式动机. 模式定义代理模式(Proxy Pattern) :给某一个对象提

菜鸟版JAVA设计模式—从买房子看代理模式

今天学习了代理模式. 相对于适配器模式,或者说装饰器模式,代理模式理解起来更加简单. 代理这个词应该比较好理解,代替去做就是代理. 比如,我们买卖房子,那么我们会找中介,我要卖房子,但是我们没有时间去卖,我主动交给中介,中介会帮我发布,会帮我找买家,带买家看房,最后我只要收到钱就行了. 买家的目的:卖房拿钱..卖加最终的目的就是把房子换成钱. 中介的工作:收集房产信息,发布房产信息,等买家打电话来,带买家看房,买家看中了,付钱给中介,中介办理过户手续,过户成功,抽掉自己的佣金,付钱给卖家. 卖家

设计模式(四)——代理模式(Proxy)

代理模式的参与者有:一个约束.一个代理者.一个被代理者.一个调用者 代理模式的实现很简单:还是那个房子,对于开门这个操作,我更换了一个远程解锁的门,那么我就可以通过这个远程连接的服务器远程解锁,这样我家里人没带钥匙,我也可以远程解锁了,而且不需要钥匙,甚至完全不需要知道锁的存在,我代码实现一下 /// <summary> /// 抽象接口 用来进行约束 /// </summary> public interface IAccess { void Access(); } /// &l