在UITableView中针对某个Cell的操作

要针对某个UITableView中的Cell做些操作,比如对这个Cell的内容进行查看详细、编辑、删除、或者触发其他功能比如发短信、打电话等,删除、和点击这个Cell在UITableView的Delegate方法中提供,其他的操作就需要识别Cell上的控件(比如Button)对应的action是针对这个Cell的。

一种常用的方式是使用view的层次,在action中找到这个Cell:在

1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

方法中,把这个Cell的Button加入到Cell的contentView的subView,并且为这个button添加Target。

1
2
3
// Button 操作
[cell.contentView addSubview:cell.button];
[cell.button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];

之后在对应的

1
- (void)buttonAction:(id)sender

action中,通过view的层次,去找到对应的Cell:

1
2
3
4
5
6
7
8
// iOS7 之前
- (void)editRemindAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
  // 继续其他的处理
}

iOS7之后出的问题

在iOS7之后,这样的办法会报错,错误在通过

1
UITableViewCell *cell = (UITableViewCell *)[[]button superview] superview];

的方式,得到的不是cell,所以在这行以下用到cell的地方,就会抛出异常。

原因是在iOS7中,在 UITableViewCell 和 UITableViewCell的ContentView之间,还有一个UITableViewCellScrollView,所以通过两次superview往上“爬”,是爬不到UITableViewCell的。

解决方式

直观地看,就是向上爬三次superview就行了。为了更好地处理这个问题,应该建立一个UIView的Category(因为这里使用的view的层次superview是UIView的方法),写个Category方法来区分不同情况来得到Cell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@implementation UIView (GetCellFromContentviewSubview)
- (UITableViewCell *)getCellFromContentviewSubview
{
    if ([[[self superview] superview] isKindOfClass:[UITableViewCell class]]) {
        return (UITableViewCell *)[[self superview] superview];
    }
    else if ([[[[self superview] superview] superview] isKindOfClass:[UITableViewCell class]]) {
        return (UITableViewCell *)[[[self superview] superview] superview];
    }
    else{
         NSLog(@"Something Panic Happens");
    }
    return nil;
}
@end

之后,把

1
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];

替换成

1
UITableViewCell *cell = (UITableViewCell *)[button getCellFromContentviewSubview];

就可以了。

讨论

另外一种办法是给控件的tag附上indexPath.row,之后在action中通过tag来得到对应的cell,但如果Cell不是静态的,indexPath.row是会变的。所以这不是一个好的办法。

但我所提供的这个办法,在stackoverflow上有1人给vote down,不知道为什么被vote down。这种办法有什么问题吗?

药提醒你

app_store_badge


BB提醒, 做最好的用药提醒工具!


BB提醒,为您提供以下十大功能:

1. 重复周期灵活多变

* 可以设置多种重复周期的提醒,例如每3天1次、每1天3次等

2. 方便快捷地通知ta

* 总有那么几个人,是您在乎的,您很关心他们的健康,不管是治病的药还是保健品,您都希望ta能按时按量想着吃,BB可以让您非常方便地通过微信、短信、电话等多种方式提醒ta!

3. 掌控过去、现在和将来

* 近期提醒列表和历史提醒列表,让您一目了然过去、现在和将来在发生什么。有的时候被动地等待提醒,不如主动地了解情况,不知您是否也有同感?

4. 标记状态不怕忘

* 吃了,点一下就标记上了绿色;不打算吃了,想跳过这次,再点一下就标记上黄色;该吃没吃的,会显示红色。有时候知道今天要吃药,但想不起来那会儿到底是吃了还是没吃,这回不必纠结了,BB帮您记着!

5. 自动更新剩余药量

* 如果您填写了总药量,BB根据每次用药的情况,自动更新剩余的药量,当剩余药量不足3次时,给出提示

6. 怕忘模式

* 开启怕忘模式,BB会按照您设定的时间间隔不停地提醒您,直到打开app才停止。有时候您怕没听见而错过提醒,那就开启怕忘模式吧↖(^ω^)↗

7. 隐秘模式

* 开启隐秘模式,提醒您的消息中,不含药品信息。这样不管多个性的铃声都不怕其他人凑上来看了↖(^ω^)↗

8. 个性铃声

* 收录了不少个性铃声,大多数都是我用iTunes剪辑出来的,如果您觉得不好,那就是我的品位太差了,不好意思啊!如果您觉得好,那咱们就是所见略同了↖(^ω^)↗

9. 背景图片

* 自定义背景图片,可以让BB更温暖、更亲切、更有爱!↖(^ω^)↗

10. 持续改进

* 这个是在说我啦~我是个上进、充满阳光和正能量的人,熟悉我的朋友都知道,我最擅长的两个字叫“加油”!BB提醒接下来还有很多要改进和升级的地方,也请您提出改进意见,怕忘模式、隐秘模式、个性铃声,都是以前使用“药提醒你”的小伙伴们提出的有爱意见,在这也顺道感谢你们啦!所以,我们一起加油,让BB提醒能够持续改进! 

反馈:“BB提醒/药提醒你” V1.0/V1.0.1/V1.1/V2.0

BB提醒,产品介绍

反馈bug、意见和建议,欢迎发邮件到:bigbelldev@gmail.com

如果您不方便写邮件,也可以在这留言~

哪些bug是要修复的? 哪些功能是很需要的?

1. 提醒声音可设置

有位同学建议提醒声音长一些或是可以循环提醒。

“有些老人或工作过于忙碌的人,有时候响一下,他们可能并不敏感或以为是条普通短信或手头有事直接就忘记了。”

这位同学说的对啊~

预计在2.0版本实现。

2. 隐私保护

有位同学建议增加个app密码功能。

恩,听了一下她的解释,我也觉得挺有必要的。

预计在2.0版本实现。


感谢热心反馈的同学们,希望这款用药提醒的工具能够越做越好!

我的这个博客的副标题叫从白痴到大师的点滴积累,不知道有多少小伙伴和我是一样的想法?

我们刚生下来时,都是白痴,懵懂地看着这个世界。随着一步步地成长,你有了一点一滴的积累,逐渐地,你在某些方面不再是白痴,甚至你成为了那方面的大师。 我们在接触一门新技术的时候,刚开始都是白痴,然后你开始成长,成长可能快、可能慢。最后你可能成为了大师,也可能成为了炮灰。每个人的精力有限,他最多也只能在有限的几个方面成为大师,选好方向很重要,别在每个方向上都成了炮灰。

我现在开始学习iOS开发技术,也就是开始做起了白痴。我想我会比其他人学得慢些,因为我基础相当差,我不是计算机科班出身,而且我只会纯C。没接触过C++、Java这两个打面向对象基础的语言。我还有2年的时间没有接触代码,这两年去做产品经理了。所以这次学习iOS开发技术的起点,算是和一个上过C语言课程的大二同学,差不多。

我想初学iOS开发技术的孩纸们,像我这种水平的还是很多的吧,不然不会有那么多培训公司的做广告了。

当然,培训公司做广告的另外一个原因是这技术简单,入门快,可以速成。这也是我选择这门技术入手的一个原因。我希望用最短的时间,学好一门工程技术,并且能学精通。我猴急,因为自己老大不小,自己还想做个高产的开发者,时间不等我,必须让自己快速成长起来。

我还对自己有个要求,就是要靠自学。这个要求有些过分是不是?又要自己成长得快,又要靠自己学,而且自己还没啥基础,这不是又让马儿跑又不给马儿吃草么?恩,是有难度。对我来讲,从产品转技术,是做了很大的决定,就像原来使用刀,现在决定使用剑,我能不能用好剑,还不是百分百的确定,怎么来确定?就是给我一把剑,舞一舞,上战场砍砍人,看看是胜是败。如果这个过程有人一直帮你拿着剑,你怎么能看出自己用剑的潜力呢?选个自己能做得好的方向很重要,不然小心成为炮灰。

在之前的学习中,我学习了几个控件的使用,也学习了几个OC概念,都做了demo,但觉得这样没法说自己啥时候就算是入了iOS技术的门。咋样能算入门呢?得系统地理解iOS的技术;能娴熟应用;能紧跟趋势。这就入门了。

想入门,首先还是得做一个完整的app,这个完整的app需要是个值得上架的产品。在做这么个产品的过程中,会涉及到iOS技术的方方面面,希望这些方面能较为系统地覆盖iOS技术的体系。

我的这个计划从8月上旬开始,在8月9日完成了产品的设计,8月10~18日对产品可能涉及到的技术点进行了预研,做了些测试,8月19日开始开始开发。在过去的这9天的开发工作中,收获实在是大!每天都要解决很多问题,很多问题的解决方法会让自己加深对iOS相关技术的理解。

这会儿正有个烦心的问题需要找原因和解决方案,我打算take a break,换换脑子,回头想想这几天的收获,会心一笑,于是打算唠叨几句写下来^_^。

想让自己快速进步,就是压迫自己亮亮剑。实际做个产品,对学习iOS技术来讲,非常有帮助。学习其他技术是不是也是一样?我猜可能是,这个等我学习其他技术的时候,再做体会。忽然觉得白眉大侠是挺酷的哈,这左手屠龙刀,右手倚天剑的。希望自己别熬到眉毛都白了,才成为大师……

从现在开始,大师之路,走起~

iOS涉及到的传感器

不用查资料,用过iPhone的同学都知道。iphone中有加速度传感器,可以感知手机在哪个方向上有加速度,比如屏幕的翻转、飞行控制游戏等都是利用这个特征做的;有指南针(貌似叫陀螺仪?),可以知道你的方向;还有定位装置,可以知道你现在的位置在哪里。

加速度传感器相关功能是由CoreMotion提供;指南针、定位信息相关功能由CoreLocation提供。

CoreMotion

在CoreMotion.framework中,有下面这些类:

1
2
3
4
5
6
7
CMAccelerometerData
CMAttitude
CMDeviceMotion
CMGyroData
CMLogItem
CMMagnetometerData
CMMotionManager

每个是做什么的,可以在官方文档中阅读,就不在这翻译了。其中实现对设备加速度的识别,主要是使用CMMotionManager。

CMMotionManager

如何使用CMMotionManager?

Step1:产生一个CMMotionManager的实例mManager。

Step2:实例使用方法isAccelerometerAvailable判断加速度传感器是否可用。

Step3:如果可用,则通过方法setAccelerometerUpdateInterval设定采样频率。

Step4:最后使用startAccelerometerUpdatesToQueue:withHandler开始采样及对采样进行处理。

示例代码

我在下面的代码中,实现了一个小球在一个框中运动,运动的轨迹是根据手机的倾斜角度计算,运动的方向同倾斜的角度一致,并且倾斜角度越大运动速度越快。 代码下载 在代码的实现过程中,对view的层次有了更深的体会。此外,在给label供数的时候,发现刚好使用代理的方式,算是也对代理做了联系。

编码过程中遇到七七八八问题的记录

Code Sign error:

着手时,借鉴了这个代码,在编译时遇到了这个问题:

Code Sign error: The identity 'iPhone Developer: Haomian Wang (33P29785DD)' doesn't match any valid certificate/private key pair in the default keychain

原因:

CodeSigning签署的不是你的provisioning,没法在真机上使用。

解决办法:

在TARGETS中的Build Settings里,找Code Signing Identity,里面把不是自己的developer改成自己的provisioning。

注:

借鉴的这份代码是使用acceleroImeter:didAccelerate方法来处理扑捉到的加速度信息,但这个方法已经在iOS5废弃了,现在都使用CoreMotion框架来实现。

未添加CoreMotion.framework

编译自己代码时,首先出现了如下错误:

原因:

原因是代码中使用了CoreMotion,但工程中没有添加CoreMotion.framework。这很常见:在使用CoreLocation等framework时,也要想着在工程中添加framework。

解决办法: 在下图处添加CoreMotion.framework

给工程改名字导致编译不过

这是个题外话,当时想给工程改个名字,结果改了之后,编译不过。 原因:

原因都是名字、路径更改导致的找不到文件。

解决办法:

改名字注意三点:

  1. 修改了Project的名字后,Xcode会提示你一些其他地方也需要修改,你就按着提示修改;
  2. 也修改本地文件夹的名字后,注意xcode工程中的文件列表文件名是否会变为红色,如果是红色,需要你再想办法重新加一下路径;
  3. 工程中的BuildSettings,这里最好搜一下你原来的名字,进行更改。我遇到的编译不过都是这里的路径还保留着原来的名字,未作更改。

iOS手势简介

iOS的手势,就是程序识别到你在屏幕上做的一些手势动作,做出反应。常见的手势有

  • UITapGestureRecognizer
  • UISwipeGestureRecognizer
  • UIRotationGestureRecognizer
  • UIPanGestureRecognizer
  • UIPinchGestureRecognizer
  • UILongPressGestureRecognizer

其中tap还有单击、双击,Swipe还有向上、下、左、右等区分。

识别这些手势,对每种手势做个反应,没啥难度。下面总结了5个步骤,和几个特殊的地方。

使用过程分5步

step1: 声明和初始化一个手势识别器

1
2
3
4
5
6
7
8
9
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
    UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
    UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)];
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotation:)];
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];

step2:对手势识别器进行属性设定

1
2
3
4
5
6
 [doubleTap setNumberOfTapsRequired:2];
    [twoFingerTap setNumberOfTouchesRequired:2];
    [swipeLeft setNumberOfTouchesRequired:1];
    [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
    [swipeRight setNumberOfTouchesRequired:1];
    [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];

step3:把手势识别器加到view中去

1
2
3
4
5
6
7
8
9
    [self.view addGestureRecognizer:singleTap];
    [self.view addGestureRecognizer:doubleTap];
    [self.view addGestureRecognizer:twoFingerTap];
    [self.view addGestureRecognizer:swipeLeft];
    [self.view addGestureRecognizer:swipeRight];
    [self.view addGestureRecognizer:rotation];
    [self.view addGestureRecognizer:pan];
    [self.view addGestureRecognizer:pinch];
    [self.view addGestureRecognizer:longPress];

step4:出现冲突时,要设定优先识别顺序

1
2
3
4
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [singleTap requireGestureRecognizerToFail:twoFingerTap];
    [pan requireGestureRecognizerToFail:swipeRight];
    [pan requireGestureRecognizerToFail:swipeLeft];

step5:去实现处理扑捉到手势之后的动作 填写各个处理函数,如:

1
2
3
4
5
6
7
8
- (void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer
- (void)handleDoubleTap:(UITapGestureRecognizer *)gestureRecognizer
- (void)handleTwoFingerTap:(UITapGestureRecognizer *)gestureRecognizer
- (void)handleSwipe:(UISwipeGestureRecognizer *)gestureRecognizer
- (void)handleRotation:(UIRotationGestureRecognizer *)gestureRecognizer
- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
- (void)handlePinch:(UIPinchGestureRecognizer *)gestureRecognizer
- (void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer

测试代码

在下面测试代码中,实现了六个手势的处理。 代码下载

在实现的时候,有几个需要注意的地方:

注意几个小地方

区分单击双击、滑动(Swipe)和拖拽(Pan)

在识别单击双击时,逻辑上应该只有判断非双击时,才判定为单击,否则永远都只会判断为单击;在识别滑动和拖拽时也是一样,应该先判断是否是swipe,不是则才是拖拽,否则都只会识别拖拽。实现方式见上面Step4,使用requireGestureRecognizerToFail方法。

向每个方向滑动(Swipe)都是一个独立的手势

如果你想接受向多个方向的滑动,对每个方向都要声明一个手势,专门代表这个方向的滑动。向左向右就是两个,加上向上向下就是4个。

1
2
 UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];

然后,你在扑捉到滑动手势之后的处理函数中,去判断UISwipeGestureRecognizer *类型的recognizer.direction是属于:

  • UISwipeGestureRecognizerDirectionLeft
  • UISwipeGestureRecognizerDirectionUp
  • UISwipeGestureRecognizerDirectionDown
  • UISwipeGestureRecognizerDirectionRight

中的哪个,然后再进一步去处理。

编码规范很重要,毕竟你的代码除了你,还有很多人可能需要阅读。遵守一个编码规范,可以使你的代码易于理解和维护。

使用编码规范是个基础技能,采用谁家的编码规范比较好呢?看你给谁工作了。对OC,苹果、google都有自己的一套编码规范,估计其他公司也都有自己成行的编码规范。

google家写过一个被广泛接受的C++编码规范,他家的oc编码规范是结合了苹果家的oc规范和他自家的c++规范。所以对于iOS新手,我觉得先了解一下苹果家的编码规范比较好。

苹果家的编码规范Coding Guidelines for Cocoa

简单翻译了下:

代码名称基础

基本原则

清晰

  1. 又清晰又简洁是最好的了,但简洁不如清晰重要
  2. 总的讲不要使用单词的简写,除了非常非常常用的简写以外(Acceptable Abbreviations and Acronyms),尽量使用单词全称,长点儿不要紧
  3. API的名称不要有歧义,一看你的API就知道是以什么方式做了什么事情,不要让人有疑问

一致性

做某个事情代码通常都叫这个名字,比如tag、setStringValue,那么你也这么叫。你在不确定怎么起名字的时候,可以参考一些常用的名字:Method Arguments

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...action:(SEL)aSelector
...alignment:(int)mode
...atIndex:(int)index
...content:(NSRect)aRect
...doubleValue:(double)aDouble
...floatValue:(float)aFloat
...font:(NSFont *)fontObj
...frame:(NSRect)frameRect
...intValue:(int)anInt
...keyEquivalent:(NSString *)charCode
...length:(int)numBytes
...point:(NSPoint)aPoint
...stringValue:(NSString *)aString
...tag:(int)anInt
...target:(id)anObject
...title:(NSString *)aString

前缀

前缀一般是2到3个大写之母,可以用来给类、协议、函数、常量、typedef结构起名字时用。但不要给方法用,方法存在的命名空间是类定义的。也不要给结构体的字段使用(the fields of a structure)//没明白是啥意思?

Prefix Cocoa Framework
NS Application Kit
NS Foundation
AB Address Book
IB Interface Builder

字体排版规范

1 多个词在一起时,不要使用标点符号(包括下划线、斜杠等),一般词首字母大写即可。

  • 具体到方法名,第一个词首字母小些,后面的词首字母大写,不要用前缀; fileExistsAtPath:isDirectory:

  • 函数名、常量名使用相关联的类的同样的前缀,后面跟着的词首字母大写。 NSRunAlertPanel NSCellDisabled

2 避免使用下划线来命名私有方法名(要是命名一个实例变量名是可以的),这算是Apple的保留写法,如果使用了可能会和已存在的函数重名。

类和协议名

类名中应该包含一个名词来说明这个类(或者类的对象)是做什么的。并且这个雷鸣应该有个合适的前缀。例如NSString、NSDate、NSButton、UIApplication等等。

协议应该按照他们的行为命名

1 多数协议是一组方法的集合,并不是专门为了某个类服务的。这类协议的命名要区别于类的命名样子,一般都是加个ing

NSLocking Good
NSLock Poor (seems like a name for a class)

2 还有一些协议是把一些没啥关系的方法放在一起,这种协议一般是协助一个类。这种情况下,这种协议可以和类名一样。例子就是NSObject。

头文件

1 定义一个独立的类或协议,这时类名和h文件名一样

Header file Declares
NSLocale.h The NSLocale class.

2 定义关联的一些类或协议,一般使用最初最基本的那个类的名字

Header file Declares
NSString.h NSString and NSMutableString classes.
NSLock.h NSLocking protocol and NSLock, NSConditionLock, and NSRecursiveLock classes.

3 包含Framework的头文件,使用framework的名字+.h,包含这个framework的公共头文件。

Header file Framework
Foundation.h Foundation.framework.

4 给另外一个framwork中的类增加API时,应该延用原始类的名字。例如NSBundleAdditions.h header file of the Application Kit

5 相关联的函数和数据类型在一起时,使用一个最贴切的名字做头文件。例如NSGraphics.h (Application Kit),包含了相关的函数、常量、结构体、数据类型等。

以上是基础的明明规则,在苹果家的代码规范中,接下来分别介绍了方法命名、函数命名、属性和数据类型命名。新手都应该好好阅读下。

最后还专门为framework开发者提供了一些Tips和Techniques。有兴趣的童鞋也可好好阅读下。

学一门新技术,需要有多个条件放在一起,才能学好。都需要哪些条件,仁者见仁,淫者见淫……但至少有一条,就是你需要跟前辈们学。

很多前辈有技术博客,及时地阅读他们的著作是个不错的提升自己的方式。此外,很多网站资源也不错,订阅来看很方便。google reader不在了,在mac下,使用什么不花钱的工具阅读RSS呢?

尝试一番后我最后选择了使用免费版的fresh feed。 先后尝试过:

  1. 此外尝试了mac下的应用RSS Bot,这个也还成,不过预览的时候,不够方便,只能看到标题,之后就得点击链接在网页里看。
  2. 还尝试了Instant RSS Notifier(free版),这个免费版太烂了。
  3. mail里原来是支持RSS阅读的,和看邮件一样看RSS,多好啊,可现在也不支持了。RSS就这么不受待见么?

综合来看还是fresh feed好用些。

P.S. 在尝试过程中,安装了获取RSS feed的Safari插件subscribe-to-feed-1-0b4,安装插件后,会出现RSS图标RSS,点击图标后,会在地址栏得到当前safari页面的feed。

什么是delegation

delegation[ˌdelɪ’ɡeɪʃn],中文叫委托,是两个类之间传递信息的一种方式。也是一种设计模式。

其作用和实现过程可以这么理解:

A类:A正在工作中发现,有的工作自己做不方便,需要委托别人帮忙做。A要制定个协议,委托的人要遵守这个协议,按照协议中的方法把工作给做了。A的属性有遵守这个协议的delegate,A知道这个delegate会帮助完成协议中的工作。

B类:B会受A委托,B类需要接受这个协议,把协议中的必须执行的方法给执行了。B有个属性是A的对象,在B类中把A的对象的delegate设置成B。

这里提到的协议,即protocol,不熟的孩纸可以仔细阅读协议(Protocol)的用法和代码例子

什么时候使用delegation

类之间传递信息可以有多种机制,除了delegation还有notification、observer等方式。一般两个类之间有点儿关系(比如view和subview,view和controller之间,使用delegate)的时候,经常使用delegation;两个模块之间没有啥关系,可能使用notification会更好。有兴趣的孩纸推荐阅读一下When to use Delegation, Notification, or Observation in iOS

在我们使用控件如textField、textView等时,都会碰到他们的delegation,这是非常好的delegation的例子,要好好去理解delegation的功效。

delegation实践

模拟场景

张老师在外地开会,她会发短信告诉学生代表什么时候让学生们放假,学生代表承诺老师会准确传达。张老师发了短信给学生代表,说7月26日周五大家放假。

设计

张老师是委托人,学生代表是受委托人,她和学生代表定的协议中的方法:由学生代表告诉学生们什么时候放假。 张老师发短信给学生代表这个时候会触发他们之间协议的方法。

测试代码

测试代码中有老师和学生代表两个类,输出的结果见NSLog。代码下载