代理

代理

  • 思路:如果某个控件需要做某件事,自己没法做,就让代理去做,通知代理去做某件事,而代理要做这件事需要两个参数:谁让它做,和做这件事的一个参数(这个参数也可以没有)。如果代理实现了代理方法,那么这个控件就把这两个参数传给代理。最后代理根据这两个参数在实现的代理方法里把事情完成。

案例一:传数据给代理(类似tableView的监听类型的代理方法)

  • 传递控制器里面:如果代理实现了_editDelegate respondsToSelector:@selector(editVc:didSaveUser:)方法,那么就调用[_editDelegate editVc:self didSaveUser:_nUser]方法把(XMGEditViewController)self和(XMGUser *)newUser这两个参数传过去
if ([_editDelegate respondsToSelector:@selector(editVc:didSaveUser:)]) {
            [_editDelegate editVc:self didSaveUser:_nUser];
        }
  • 传递控制器头文件里:申明代理方法,代理属性
@protocol XMGEditViewControllerDelegate <NSObject>
@optional
- (void)editVc:(XMGEditViewController *)editVc didSaveUser:(XMGUser *)newUser;

@end
@property (weak,nonatomic) id <XMGEditViewControllerDelegate> editDelegate;
  • 接受控制器里:遵守协议,成为代理editVc.editDelegate = self;,并且实现方法,接受数据得到传值
- (void)editVc:(XMGEditViewController *)editVc didSaveUser:(XMGUser *)newUser{
    self.allDetailVc.nUser = newUser;
}

案例二:代理成为数据源(类似tableView里的数据源代理)

  • 自定义View头文件里:
@protocol  XMGWaterFlowLayoutDelagte<NSObject>
@optional
-(CGFloat)waterFlowLayout:(XMGWaterFlowLayout *)layout cellHeightWithCellWidth:(CGFloat)cellWidth atIndexPath:(NSIndexPath *)indexPath;
@end
@property (nonatomic, weak) id<XMGWaterFlowLayoutDelagte> delegate;
  • 自定义的View.m里:
        // 如果代理实现了代理方法,那么h就等于这个方法的返回值
        if ([self.delegate respondsToSelector:@selector(waterFlowLayout:cellHeightWithCellWidth:atIndexPath:)]) {
            h = [self.delegate waterFlowLayout:self cellHeightWithCellWidth:w atIndexPath:indexPath];
  • 外界控制器里:实现代理方法,传输数据
-(CGFloat)waterFlowLayout:(XMGWaterFlowLayout *)layout cellHeightWithCellWidth:(CGFloat)cellWidth atIndexPath:(NSIndexPath *)indexPath{
    return 100;
}

拿别的对象作为代理

  • 注意:代理是弱引用,所以要拿别的对象作为代理,下面这么做是错的
  • 所以一般用控制器作为代理,因为控制器不会死
scrollView.delegate = [[XMGCat alloc] init];//这个猫刚创建就死了
  • 必须再拿一个强指针指着它
@property (nonatomic, strong) XMGCat *cat;
self.cat = [[XMGCat alloc] init];
scrollView.delegate = self.cat;
  • 为什么代理用弱指针?
    • 因为一般用控制器作为代理,如果用强指针,那么控制器经过循环会强引用代理,代理再强引用控制器,循环强引用,那么他们永远不会死了

代理的名称规律

  • 协议名称一般是控件类名+delegate,比如UIScrollViewDelegate
  • 代理方法一般是控件名开头,比如UIScrollView的代理方法一般以UIScrollView开头

代理与通知的选择

  • 共同点 :利用通知和代理都能完成对象之间的通信(比如A对象告诉D对象发生了什么事情, A对象传递数据给D对象)

  • 不同点 :

    • 代理 : 1个对象只能告诉另1个对象发生了什么事情
    • 通知 : 1个对象能告诉N个对象发生了什么事情, 1个对象能得知N个对象发生了什么事情
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值