zoukankan      html  css  js  c++  java
  • IOS 学习笔记 2015-03-27 我理解的OC-代理模式

    案例1

    KCButton.h
    
    //
    //  KCButton.h
    //  Protocol&Block&Category
    //
    //  Created by Kenshin Cui on 14-2-2.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @class KCButton;
    
    //一个协议可以扩展另一个协议,例如KCButtonDelegate扩展了NSObject协议
    @protocol KCButtonDelegate <NSObject>
    
    @required //@required修饰的方法必须实现
    -(void)onClick:(KCButton *)button;
    
    @optional //@optional修饰的方法是可选实现的
    -(void)onMouseover:(KCButton *)button;
    -(void)onMouseout:(KCButton *)button;
    
    @end
    
    @interface KCButton : NSObject
    
    #pragma mark - 属性
    #pragma mark 代理属性,同时约定作为代理的对象必须实现KCButtonDelegate协议
    @property (nonatomic,retain) id<KCButtonDelegate> delegate;
    
    #pragma mark - 公共方法
    #pragma mark 点击方法
    -(void)click;
    
    @end
    KCButton.m
    
    //
    //  KCButton.m
    //  Protocol&Block&Category
    //
    //  Created by Kenshin Cui on 14-2-2.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import "KCButton.h"
    
    @implementation KCButton
    
    -(void)click{
        NSLog(@"Invoke KCButton's click method.");
        //判断_delegate实例是否实现了onClick:方法(注意方法名是"onClick:",后面有个:)
        //避免未实现ButtonDelegate的类也作为KCButton的监听
        if([_delegate respondsToSelector:@selector(onClick:)]){
            [_delegate onClick:self];
        }
    }
    
    @end
    MyListener.h
    
    //
    //  MyListener.h
    //  Protocol&Block&Category
    //
    //  Created by Kenshin Cui on 14-2-2.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    @class KCButton;
    @protocol KCButtonDelegate;
    
    @interface MyListener : NSObject<KCButtonDelegate>
    -(void)onClick:(KCButton *)button;
    @end
    MyListener.m
    
    //
    //  MyListener.m
    //  Protocol&Block&Category
    //
    //  Created by Kenshin Cui on 14-2-2.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import "MyListener.h"
    #import "KCButton.h"
    
    @implementation MyListener
    -(void)onClick:(KCButton *)button{
        NSLog(@"Invoke MyListener's onClick method.The button is:%@.",button);
    }
    @end
    main.m
    
    //
    //  main.m
    //  Protocol&Block&Category
    //
    //  Created by Kenshin Cui on 14-2-2.
    //  Copyright (c) 2014年 Kenshin Cui. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "KCButton.h"
    #import "MyListener.h"
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            
            KCButton *button=[[KCButton alloc]init];
            MyListener *listener=[[MyListener alloc]init];
            button.delegate=listener;
            [button click];
            /* 结果:
             Invoke KCButton's click method.
             Invoke MyListener's onClick method.The button is:<KCButton: 0x1001034c0>.
             */
        }
        return 0;
    }
    我们通过例子模拟了一个按钮的点击过程,有点类似于Java中事件的实现机制。通过这个例子我们需要注意以下几点内容:
    
    id可以表示任何一个ObjC对象类型,类型后面的”<协议名>“用于约束作为这个属性的对象必须实现该协议(注意:使用id定义的对象类型不需要加“*”);
    MyListener作为事件触发者,它实现了KCButtonDelegate代理(在ObjC中没有命名空间和包的概念,通常通过前缀进行类的划分,“KC”是我们自定义的前缀)
    在.h文件中如果使用了另一个文件的类或协议我们可以通过@class或者@protocol进行声明,而不必导入这个文件,这样可以提高编译效率(注意有些情况必须使用@class或@protocol,例如上面KCButton.h中上面声明的KCButtonDelegate协议中用到了KCButton类,而此文件下方的KCButton类声明中又使用了KCButtonDelegate,从而形成在一个文件中互相引用关系,此时必须使用@class或者@protocol声明,否则编译阶段会报错),但是在.m文件中则必须导入对应的类声明文件或协议文件(如果不导入虽然语法检查可以通过但是编译链接会报错);
    使用respondsToSelector方法可以判断一个对象是否实现了某个方法(需要注意方法名不是”onClick”而是“onClick:”,冒号也是方法名的一部分);
    属性中的(nonatomic,retain)不是这篇文章的重点,在接下来的文章中我们会具体介绍。

    案例2

    //
    //  WPContactsViewController.h
    //  OC-UI-表单-单元格
    //
    //  Created by wangtouwang on 15/3/26.
    //  Copyright (c) 2015年 wangtouwang. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    
    @interface WPContactsViewController : UIViewController
    {
        UITableView *_tableView;//表单UI控件
        NSMutableArray *_mutableArrayContacts;//联系人集合模型
        NSIndexPath *_selectedIndexPath;//当前选中的组和行
    }
    
    @end
    //
    //  WPContactsViewController.m
    //  OC-UI-表单-单元格
    //
    //  Created by wangtouwang on 15/3/26.
    //  Copyright (c) 2015年 wangtouwang. All rights reserved.
    //
    
    #import "WPContactsViewController.h"
    #import "WPContacts.h"
    #import "WPContactsGroup.h"
    
    @interface WPContactsViewController ()<UITableViewDataSource,UITableViewDelegate,UIAlertViewDelegate>
    
    @end
    
    
    @implementation WPContactsViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        //初始化数据
        [self initObjectData];
        
        //创建一个分组样式的UITableView
        _tableView=[[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
        
        //设置数据源,注意必须实现对应的UITableViewDataSource协议
        _tableView.dataSource=self;
        
        //设置代理
        _tableView.delegate=self;
        
        [self.view addSubview:_tableView];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    #pragma mark 加载数据
    -(void)initObjectData{
         _mutableArrayContacts=[[NSMutableArray alloc]init];
        
        WPContacts *contact1=[WPContacts initStaticWithFirstName:@"Cui" andLastName:@"Kenshin" andPhoneNumber:@"18500131234"];
        WPContacts *contact2=[WPContacts initStaticWithFirstName:@"Cui" andLastName:@"Tom" andPhoneNumber:@"18500131237"];
        WPContactsGroup *group1=[WPContactsGroup initStaticWithName:@"C" andDescript:@"With names beginning with C" andConcats:[NSMutableArray arrayWithObjects:contact1,contact2, nil]];
        [_mutableArrayContacts addObject:group1];
     
        
        WPContacts *contact3=[WPContacts initStaticWithFirstName:@"Dui" andLastName:@"JACK" andPhoneNumber:@"13712133321"];
        WPContacts *contact4=[WPContacts initStaticWithFirstName:@"Dui" andLastName:@"LUCY" andPhoneNumber:@"13712133322"];
        WPContactsGroup *group2=[WPContactsGroup initStaticWithName:@"D" andDescript:@"With names beginning with D" andConcats:[NSMutableArray arrayWithObjects:contact3,contact4, nil]];
        [_mutableArrayContacts addObject:group2];
        
    }
    
    #pragma mark 返回分组数
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
        NSLog(@"计算分组数");
        return _mutableArrayContacts.count;
    }
    
    #pragma mark 返回每组行数
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        NSLog(@"计算每组(组%lu)行数",(unsigned long)section);
    //    WPContactsGroup *group1 = _mutableArrayContacts[section];
        return  ((WPContactsGroup *)_mutableArrayContacts[section])._concats.count;
    }
    
    #pragma mark返回每行的单元格
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
         NSLog(@"生成单元格(组:%lu,行%lu)",(unsigned long)indexPath.section,(unsigned long)indexPath.row);
       WPContactsGroup *group= _mutableArrayContacts[indexPath.section];
        WPContacts *contacts = group._concats[indexPath.row];
        UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
        cell.textLabel.text=[contacts getName];
        cell.detailTextLabel.text = [contacts _phoneNumber];
        return cell;
    }
    
    #pragma mark 返回每组头标题名称
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
         NSLog(@"生成组(组%lu)名称",(unsigned long)section);
        WPContactsGroup *group =  _mutableArrayContacts[section];
        return group._name;
    }
    
    #pragma mark 返回每组尾部说明
    - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
        NSLog(@"生成尾部(组%lu)详情",(unsigned long)section);
        return ((WPContactsGroup *)_mutableArrayContacts[section])._descript;
    }
    
    
    #pragma mark 生成索引
    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
        NSLog(@"生成组索引");
        NSMutableArray *indexs = [[NSMutableArray alloc] init];
        for (WPContactsGroup *group in _mutableArrayContacts) {
            [indexs addObject:group._name];
        }
        return indexs;
    }
    
    #pragma mark 设置分组标题高度
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
        NSLog(@"设置分组标题高度");
        return 25;
    }
    
    #pragma mark 设置分组尾部内容高度
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
        NSLog(@"设置分组尾部内容高度");
        return 20;
    }
    
    #pragma mark 设置每行高度
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
           NSLog(@"设置每行高度");
        return 30;
    }
    
    #pragma mark 复写设置点击行触发事件(复写的方法是在TableViewDelegate协议中已有,回调)
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        NSLog(@"触发我吧");
         _selectedIndexPath=indexPath;
        //获取单元格包装的对象WPContacts
       WPContacts *contacts = ((WPContactsGroup *)_mutableArrayContacts[indexPath.section])._concats[indexPath.row];
        //初始化弹出框
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"System Info" message:[contacts getName] delegate:self cancelButtonTitle:@"Cancle" otherButtonTitles:@"OK", nil];
        //设置窗口样式
        alertView.alertViewStyle=UIAlertViewStylePlainTextInput;
        //获取文本框
        UITextField *textFild =  [alertView textFieldAtIndex:0];
        //设置文本框内容
        textFild.text = contacts._phoneNumber;
        //显示窗口
        [alertView show];
    }
    
    #pragma mark 设置弹出框后续按钮事件 复写UIAlerViewDelegate协议 的点击按钮 clickedButtonAtIndex方法
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        NSLog(@"设置弹出框后续按钮事件 clickedButtonAtIndex");
        if (buttonIndex==1) {
            //获取文本框内容
            NSString *phoneNumber = [alertView textFieldAtIndex:0].text;    
            //获取选中的UITableViewCell 包装的对象
           WPContacts *contacts =  ((WPContactsGroup *)_mutableArrayContacts[_selectedIndexPath.section])._concats[_selectedIndexPath.row];
            contacts._phoneNumber = phoneNumber;
            
             NSArray *indexPaths=@[_selectedIndexPath];//需要局部刷新的单元格的组、行
                //此处优化 将全局跟新 该变到 选择行 局部更新
            [_tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];
            
            //[_tableView reloadData];
        }
    }
    
    @end
     
  • 相关阅读:
    linux下vim命令详解
    Linux 指令篇:档案目录管理chown
    分级渲染百度地图路段红黄绿功能
    矢量数据的属性值的添加、编辑、删除
    Extjs+C# 文件上传
    IBATIS 的动态SQL语句拼接
    一个DIV位于另一个div的右下角
    ArcGIS JavaScript API 添加点
    将Excel数据导入至SqlServer中
    Extjs 图表控件,可修改X轴与Y轴坐标
  • 原文地址:https://www.cnblogs.com/ak23173969/p/4371489.html
Copyright © 2011-2022 走看看