zoukankan      html  css  js  c++  java
  • iOS 层层推进实现代理模式

    1.代理模式核心思想:A类委托B类做某件事,然后A类获取B类的执行的返回结果!

    举例:女孩想去买电影票,但是自己不亲自去而是委托男孩了解电影电影票信息,同时女孩获得男孩买票的结果,代码模拟实现:

    /*********************************** Gril.h *************************************/
    #import <Foundation/Foundation.h>
    @class Boy;
    @interface Gril : NSObject
    
    // “女孩”想去买电影票
    - (void)buyTicket;
    
    // “女孩”声明自己的代理对象
    @property (nonatomic,retain) Boy *boy;
    // @property (nonatomic,retain) Boy *delegate;
    
    @end
    /*********************************** Gril.m *************************************/
    #import "Gril.h"
    #import "Boy.h"
    
    @implementation Gril
    
    // “女孩”想买电影票
    - (void)buyTicket
    {
       // “女孩”直接获取自己的代理(“男孩”)的方法返回值 剩余电影票的个数
       int count = [_boy leftTicketsCount];
       // “女孩”直接获取自己的代理(“男孩”)的方法返回值 单张电影票的价格
       double price = [_boy ticketPrice];
        
       // 输出女孩获得的信息
       NSLog(@"还剩%d张电影票,每张票价是%.2f元",count,price);
    
    }
    
    // Girl类引用了Boy类 那么在Girl类释放之前先释放Boy对象
    - (void)dealloc
    {
        [_boy release];
        [super dealloc];
    }
    @end
    /*********************************** Boy.h *************************************/
    #import <Foundation/Foundation.h>
    
    @interface Boy : NSObject
    
    // 查询单张票价
    - (double)ticketPrice;
    // 查询还剩多少张电影票
    - (int)leftTicketsCount;
    
    @end
    /*********************************** Boy.m *************************************/
    #import "Boy.h"
    @implementation Boy
    
    
    // 实现单张票价的查询
    - (double)ticketPrice
    {
        return 20;
    }
    
    // 实现剩余的电影票
    - (int)leftTicketsCount
    {
        return 3;
    }
    @end
    /*********************************** main.m *************************************/
    #import <Foundation/Foundation.h>
    #import "Boy.h"
    #import "Gril.h"
    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            Gril *gril = [[[Gril alloc] init] autorelease];
            Boy *boy = [[[Boy alloc] init] autorelease];
            
            // 为girl中的boy属性赋值 完成"代理思想"
            gril.boy = boy; // gril.delegate = boy;
            
            [gril buyTicket];
           
        }
        return 0;
    }

     小结:可以看出Gril类的代理对象已固定是Boy类,这样的话代码耦合性太强,如果下次需要修改Gril类的代理对象为其他对象则不便于修改

     修改后的代码如下:

    /*********************************** Gril.h *************************************/
    #import <Foundation/Foundation.h>
    #import "TicketDelegate.h"
    @class Boy;
    
    @interface Gril : NSObject
    
    // “女孩”想去买电影票
    - (void)buyTicket;
    
    // “女孩”声明自己的代理对象为任意对象 但是对象必须遵守TicketDelegate协议
    @property (nonatomic,retain) id<TicketDelegate> delegate; //  这样的话 任何对象都可以作为代理对象 只要遵守协议即可
    
    @end
    /*********************************** Gril.m *************************************/
    #import "Gril.h"
    #import "Boy.h"
    
    @implementation Gril
    
    // “女孩”想买电影票
    - (void)buyTicket
    {
       // “女孩”直接获取自己的代理(“男孩”)的方法返回值 剩余电影票的个数
       int count = [_delegate leftTicketsCount];
       // “女孩”直接获取自己的代理(“男孩”)的方法返回值 单张电影票的价格
       double price = [_delegate ticketPrice];
        
       // 输出女孩获得的信息
       NSLog(@"还剩%d张电影票,每张票价是%.2f元",count,price);
    
    }
    
    // Girl类引用了Boy类 那么在Girl类释放之前先释放Boy对象
    - (void)dealloc
    {
        [_delegate release];
        [super dealloc];
    }
    @end
    // 定义协议
    /*
    **************************** TicketDelegate.h文件 ******************************/ #import <Foundation/Foundation.h> // 定义协议:那么代理对象必须要遵循协议 @protocol TicketDelegate <NSObject> // 查询单张票价 - (double)ticketPrice; // 查询还剩多少张电影票 - (int)leftTicketsCount; @end
    /*********************************** Boy.h *************************************/
    #import <Foundation/Foundation.h>
    #import "TicketDelegate.h"
    
    // 声明代理对象要遵守的协议
    @protocol TicketDelegate;
    
    // Boy作为Gril的代理则必须遵守协议
    @interface Boy : NSObject <TicketDelegate>
    
    @end
    /*********************************** Boy.m *************************************/
    #import "Boy.h"
    @implementation Boy
    
    
    // 实现单张票价的查询
    - (double)ticketPrice
    {
        return 20;
    }
    
    // 实现剩余的电影票
    - (int)leftTicketsCount
    {
        return 3;
    }
    @end
    /*********************************** main.m *************************************/
    #import <Foundation/Foundation.h>
    #import "Boy.h"
    #import "Gril.h"
    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            Gril *gril = [[[Gril alloc] init] autorelease];
            Boy *boy = [[[Boy alloc] init] autorelease];
            
            // 为girl中的boy属性赋值 完成“代理思想”
            gril.delegate = boy; // gril.delegate = boy;
            
            [gril buyTicket];
        }
        return 0;
    }

    小结:修改后的代码耦合性相对来比较弱!假设如果再要为Gril类添加代理对象,Gril类本身不需要任何修改,只要新建的代理对象遵守协议即可

    2.联想UITableView要显示内容时它本身并不知道要显示要分几组、每组显示多少行、每行显示的内容等,也是要依靠它的代理对象UITableViewDataSource来执行返回的结果会赋值给UITableView中的相应参数,才会进行显示

  • 相关阅读:
    IOS总结_无需自己定义UITabbar也可改变UITabbarController的背景和点击和的颜色
    破解中国电信华为无线猫路由(HG522-C)自己主动拨号+不限电脑数+iTV
    HDUJ 2074 叠筐 模拟
    CSRF——攻击与防御
    Ant命令行操作
    C#软件开发实例.私人订制自己的屏幕截图工具(七)加入放大镜的功能
    qemu-kvm-1.1.0源代码中关于迁移的代码分析
    FileSystemWatcher使用方法具体解释
    configure交叉编译
    海量图片存储策略
  • 原文地址:https://www.cnblogs.com/QM80/p/3624635.html
Copyright © 2011-2022 走看看