iOS开发常见问题集之Delegate

2017-01-03  本文已影响311人  刘帅_

0 关键词

代理模式、delegate

1 概述

Delegate是Cocoa的精髓之一,Delegate在Cocoa及各大框架下出现频率极高,很少有框架像Cocoa这样对代理模式如此痴迷,因此Delegate在iOS/MacOS开发中的重要性不言而喻。不过近年来Block在官方新API出现的频率明显增多,Block取代Delegate完成了不少功能。但Delegate仍然大量存在于Cocoa框架之中。

2 Delegate的声明步骤

完整的代理声明步骤如图所示,左侧是委托方(如UITableView),右侧是代理方(如UIViewController或UITableViewController)。


Delegate声明步骤

3 使用Delegate的常见问题

3.1 代理不执行

如何避免忘记指定代理
我个人一般会在添加子视图的时候指定代理,代码写法如下:

//Code in ViewController
[self.view addSubview:({
        _tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
        _tableView.dataSource = self;
        _tableView.delegate = self;
        _tableView;
    })];

()是什么
GNU C支持一种叫作Statements and Declarations in Expressions(怎么翻译?)的语法形式,可以在小括号内写多行代码,最后一行必须为返回值。这种写法在GCC和LLVM下都可编译通过。如:

({ int y = foo (); int z;
        if (y > 0) z = y;
        else z = - y;
        z; })
 #define max(a,b) ((a) > (b) ? (a) : (b))

原文出处 Statements and Declarations in Expressions

3.2 通过恰当的内存语义设置,避免引用循环

代理对象不拥有委托对象,所以属性在ARC下使用weak修饰,在MRC下使用assign修饰(现在估计很少有人使用MRC了吧)。

3.3 由代理引起的Crash

if (self.delegate && [self.delegate respondsToSelector:@selector(didClickButton:)]) {
        [self.delegate didClickButton:button];
    }

*出现 unrecognized selector sent to instance情况二
出现该问题的原因是代理对象被释放了之后委托对象又向被释放了的代理对象发送了消息。在MRC中,代理对象被设置为assign,当委托对象被释放掉之后,delegate的指针并没有被置空。所以需要在合适的时间点(例如dealloc方法内)将delegate设置为nil。在ARC中,代理对象被设置为weak,委托对象被释放时,用weak修饰的属性会自动置nil,所以不会crash。

上一篇下一篇

猜你喜欢

热点阅读