首页 > 学院 > 开发设计 > 正文

IOS学习笔记2015-03-27我理解的OC-代理模式

2019-11-14 19:21:54
字体:
来源:转载
供稿:网友

案例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];    }}@endMyListener.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;@endMyListener.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);}@endmain.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

 

 

 

 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表