美文网首页小知识点好东西
控制器瘦身-代理对象

控制器瘦身-代理对象

作者: _浅墨_ | 来源:发表于2017-09-25 19:18 被阅读18次

下面两种方式都是弱引用代理对象,但是第一种在代理对象被释放后不会导致崩溃,而第二种会导致崩溃。

@property (nonatomic, weak) iddelegate;
@property (nonatomic, assign) iddelegate;

weak 和 assign 是一种 “非拥有关系” 的指针,通过这两种修饰符修饰的指针变量,都不会改变被引用对象的引用计数。但是在一个对象被释放后,weak会自动将指针指向nil,而assign则不会。在iOS中,向nil发送消息时不会导致崩溃的,所以assign就会导致野指针的错误unrecognized selector sent to instance。

所以我们如果修饰代理属性,还是用weak修饰吧,比较安全。

控制器瘦身-代理对象:

我们将 UITableView 的 delegate 和 DataSource 单独拿出来,由一个代理对象类进行控制,只将必须控制器处理的逻辑传递给控制器处理。

UITableView 的数据处理、展示逻辑和简单的逻辑交互都由代理对象去处理,和控制器相关的逻辑处理传递出来,交由控制器来处理,这样控制器的工作少了很多,而且耦合度也大大降低了。这样一来,我们只需要将需要处理的工作交由代理对象处理,并传入一些参数即可。

代理对象.h:

typedef void (^selectCell) (NSIndexPath *indexPath);
/**
 *  代理对象(UITableView的协议需要声明在.h文件中,不然外界在使用的时候会报黄色警告,看起来不太舒服)
 */
@interface TableViewDelegateObj : NSObject [UITableViewDelegate, UITableViewDataSource](因识别问题,这里将尖括号改为方括号)
 
/**
 *  创建代理对象实例,并将数据列表传进去
 *  代理对象将消息传递出去,是通过block的方式向外传递消息的
 *  @return 返回实例对象
 */
+ (instancetype)createTableViewDelegateWithDataList:(NSArray *)dataList
                                        selectBlock:(selectCell)selectBlock;
@end

代理对象.m:

#import "TableViewDelegateObj.h"
 
@interface TableViewDelegateObj () 
@property (nonatomic, strong) NSArray   *dataList;
@property (nonatomic, copy)   selectCell selectBlock;
@end
 
@implementation TableViewDelegateObj
+ (instancetype)createTableViewDelegateWithDataList:(NSArray *)dataList
                                        selectBlock:(selectCell)selectBlock {
    return [[[self class] alloc] initTableViewDelegateWithDataList:dataList
                                                       selectBlock:selectBlock];
}
 
- (instancetype)initTableViewDelegateWithDataList:(NSArray *)dataList selectBlock:(selectCell)selectBlock {
    self = [super init];
    if (self) {
        self.dataList = dataList;
        self.selectBlock = selectBlock;
    }
    return self;
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *identifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    cell.textLabel.text = self.dataList[indexPath.row];
    return cell;
}
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.dataList.count;
}
 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    // 将点击事件通过block的方式传递出去
    self.selectBlock(indexPath);
}
@end

使用方法示例:

self.tableDelegate = [TableViewDelegateObj createTableViewDelegateWithDataList:self.dataList 
                                                                   selectBlock:^(NSIndexPath *indexPath) {
    NSLog(@"点击了%ld行cell", (long)indexPath.row);
}];
self.tableView.delegate = self.tableDelegate;
self.tableView.dataSource = self.tableDelegate;

iOS中的回调方法有很多,而代理和block功能更加相似,都是直接进行回调,那我们应该用哪个呢,或者说哪个更好呢?

其实这两种消息传递的方式,没有哪个更好、哪个不好直说....我们应该区分的是在什么情况下应该用什么,用什么更合适!下面我将会简单的介绍一下在不同情况下代理和block的选择:

从性能上来说,block的性能消耗要略大于delegate,因为block会涉及到栈区向堆区拷贝等操作,时间和空间上的消耗都大于代理。而代理只是定义了一个方法列表,在遵守协议对象的objc_protocol_list中添加一个节点,在运行时向遵守协议的对象发送消息即可。

参考:

  1. 摘抄自:你真的了解iOS代理设计模式吗?

相关文章

  • 控制器瘦身-代理对象

    下面两种方式都是弱引用代理对象,但是第一种在代理对象被释放后不会导致崩溃,而第二种会导致崩溃。 weak 和 as...

  • QHP_09cell代理设计模式

    代理模式的重要性: 1.A对象监听B对象的一些行为(比如控制器监听了footer的行为),A对象成为B对象的代理(...

  • OC:抽出数据源代理

    前言: 为控制器瘦身,本文提供一个抽出数据源代理的示例,具体请结合自身的需求定制。抽出数据源代理不是必须的,如果控...

  • java动态代理

    代理模式 概念 1.真实对象:被代理的对象 2,代理对象: 3,代理模式:代理对象代理真实对象,达...

  • 控制器之间的传值(逆传)

    控制器之间的传值(逆传) 1.使用代理(自定义delegate) 步骤:a.在需要代理的控制器定义代理;b.定义代...

  • 深入理解Java动态代理

    代理模式 使用代理模式创建代理对象,让代理对象来控制对某个对象的访问, 被代理对象可以是远程对象,创建开销大的对象...

  • tabBar的代理对象不可修改特性

    call stack调用堆栈错误信息输出如下: UITabBar的代理对象是他自身的控制器,这是系统写好的!也是不...

  • Java代理模式整理

    代理模式 静态代理 给对象提供代理对象,由代理对象控制对原对象的引用。代理模式如【中介】 目的 三个角色 动态代理...

  • jdk代理和cglib代理

    代理:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。jdk代理跟cglib代理都是动态代理...

  • 代理模式

    1、什么是代理模式 定义:给目标对象提供一个代理对象,并由代理对象控制目标对象的引用。在代理模式中需要代理对象和目...

网友评论

    本文标题:控制器瘦身-代理对象

    本文链接:https://www.haomeiwen.com/subject/agbdextx.html