[New learn]讲解Objective-c的block知识-实践

1.简介

在之前的文章[New learn]讲解Objective-c的block知识中介绍了block的相关知识。本章中我们将以一个实际例子来简单介绍一下block如何代替代理。

2.原有通过代理实现方式回顾

[How to] 使用Xib来创建view中我们介绍了如何通过xib来自定义table的footview,如何通过代理的方式来通知controller去加载更多数据。

相应的代码:https://github.com/xufeng79x/tableView_groupbuy_test

1.在上述项目中我们在XFLoadMoreView.h头文件中声明了一个协议

@protocol XFLoadMoreViewDelegate <NSObject>

/**
 *  当按钮点击后通知代理实现对象
 *
 *  @param loadMoreView 触发者本身
 */
@optional
-(void) loadMoreViewDidClickedToLoadBtn:(XFLoadMoreView *) loadMoreView;

@end

2.在自定义的XFLoadMoreView中声明了代理属性:

 代理属性,指向显示了此代理的对象,防止循环引用需要使用weak属性参数
@property (nonatomic,weak) id<XFLoadMoreViewDelegate> delegate;

3.在controller中去实现了此协议,并在创建XFLoadMoreView实例的时候将其代理属性值设定为当前controller,以此来进行通知调用。

@interface XFGoodsShowsViewController () <UITableViewDataSource, XFLoadMoreViewDelegate>
。。。。。。。。。。。

// 加载按钮按下后通知到此对象调用此方法
-(void) loadMoreViewDidClickedToLoadBtn:(XFLoadMoreView *) loadMoreView
{
    // 这里我们模拟增加一个团购的信息,插入到列表的最好一行
    XFGoodModel *model = [[XFGoodModel alloc] init];
    model.image = @"image.jpg";
    model.name = @"new food";
    model.price = 123;
    model.soldNum = 321;

    // 将次信息插入到表数据源中
    [self.goodsList addObject:model];

    // 需要将此数据塞入table的最后一行
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.goodsList.count - 1 inSection:0];    [self.goodsTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];

    // 加载完毕后将table滚到新加入的行那里,也就是最后一条
    [self.goodsTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
。。。。。。。

3.使用block特性来替代代理特性机制

我们可以不使用通过协议以代理的方式去做,我们可以通过block来处理:

具体方法为:

1.在XFLoadMoreView.h文件中声明block属性,用于接收来自目标的回调block

 // 定义通知回调
@property(nonatomic,strong) void (^notifyLoadBlock)(XFLoadMoreView *);

2. 将XFLoadMoreView.m类初始化方法中增加block参数

// 利用block来进行通知回调的初始化方法
+(instancetype) loadMoreViewWithNotifyBlock:(void (^)(XFLoadMoreView *)) notifyLoadBlock
{
    // 直接从xib中加载view
    XFLoadMoreView *loadView  = [[[NSBundle mainBundle] loadNibNamed:@"XFLoadButton" owner:nil options:nil] lastObject];

    // 美化按钮,将按钮的四个角圆润化
    loadView.loadMoreBtnView.layer.cornerRadius = 5;
    loadView.loadMoreBtnView.layer.masksToBounds = YES;

    // 设定加载更多回调block
    loadView.notifyLoadBlock = notifyLoadBlock;
    return loadView;
}

3.在controller处初始化XFLoadMoreView的时候将具体block实现传入:

    // 加载tableView的footview
    XFLoadMoreView *loadMoreView = [XFLoadMoreView loadMoreViewWithNotifyBlock:^(XFLoadMoreView * view){
        [self loadMoreViewDidClickedToLoadBtn:view];
    }];

这里重复利用了原有协议方式中的方法。

4.当自定义XFLoadMoreView中发生加载事件的时候去通知controller加载数据:

/**
 *  点击加载更多按钮后触发
 */
- (IBAction)loadMoreClick {
    // 将botton隐藏让后将加载样式呈现
    self.loadMoreBtnView.hidden = YES;
    self.loadMoreIngView.hidden = NO;

    // 使用此方法能够达到延迟执行效果
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.loadMoreBtnView.hidden = NO;
        self.loadMoreIngView.hidden = YES;

        // 向代理发送信息,由于是代理定义中设置的是可选方法,所以发送信息之前需要检查是否实现了此方法
//        if ([self.delegate respondsToSelector:@selector(loadMoreViewDidClickedToLoadBtn:)])
//        {
//            [self.delegate loadMoreViewDidClickedToLoadBtn:self];
//        }

        // 使用回调进行加载通知
        if (nil != self.notifyLoadBlock)
        {
            self.notifyLoadBlock(self);
        }
    });

4.总结

在本文中我们将一个原本通过代理的方式实现的功能通过block方式实现。

那么何时应该采用代理何时应该采用block呢?

我们可以参考如下文章:http://stackoverflow.com/questions/26791548/objc-memory-usage-of-delegate-vs-block

本章代码:https://github.com/xufeng79x/BlockDemo

时间: 2024-10-10 18:15:48

[New learn]讲解Objective-c的block知识-实践的相关文章

简单总结iNode和block知识

iNode:索引节点(index node) iNode是用来存储数据属性信息的,iNode包含的属性包括:文件大小.属组.归属的用户组.读写权限.文件类型.修改时间.还包括指向文件实体的指针功能(iNode节点和block的对应关系),但是,iNode不包括文件名. Block 是用来存储实际数据的. 理解:可以把iNode理解为一本书的目录,block理解为书的每一页. iNode小结: 1)磁盘分区格式化为ext4文件系统后会生成一定数量的iNode和block 2)iNode是索引节点,

Linux系统inode和block知识详解

1. inode和block概述 在每个Linux存储设备或存储设备的分区被格式化(ext3,ext4等)之后,一般都有两部分:一部分是inode,另一部分是block.block是用来存储实际数据的,而inode用来存储这些数据的属性信息,包括文件的大小.属主.归属的用户组.读写权限.文件类型.修改时间,还包含指向文件实体的指针功能(inode节点到block的对应关系)等,但并不包含文件名.文件名一般被存储在其所在目录的block里面. inode除了记录文件属性信息外,还会为每个文件进行信

inode与block知识总结

inode概述:硬盘要分区,然后格式化,创建文件系统在每个Linux存储设备的分区被格式化为ext3文件系统后一般有两个部分:    第一部分Inode:存储这些数据的属性信息(大小,属主,归属的用户组,读写权限,文件类型,修改时间                   还包含指向文件实体的指针功能(inode节点--block的对应关系)但是不包含文件名.    第二部分Block:用来存储实际数据用的,例如:照片,视频等普通文件数据 查看inode 的总量和使用量df -i   查看inode

3-6 【文档讲解】Flutter入门基础知识

结束 原文地址:https://www.cnblogs.com/wangjunwei/p/12183196.html

3-7 【视频讲解】Flutter入门基础知识

如何创建一个flutter项目 如何运行flutter项目 如何导入widget 如何写一个hello world 左边是安卓,右边是IOS 在实现了相同功能 的程序,flutter的代码要比react native的代码量要少很多. 如何使用Widget,并将其嵌套以形成widget树 下图就是运行的效果. 如何创建可重用的widget flutter中要实现相同的功能.定义个CustomeCard这样一个类.继承了StatelessWidget 使用这个widget..传入了index这样的

C#基础知识实践

1.C#的内置类型同样很多,而且需要声明变量并且在此基础上操作,发现了一个以前不知道的东西:可以根据ASCII打出字符 还有类型转换时要注意被赋值对象的范围不能少于赋值变量的范围,此时需要将后面的变量的范围通过显示转换强行缩小并且还要保证后面变量的值仍然在缩小的范围内 还有占位符{},表示占了个位置给后面逗号紧跟着的变量 2.Braching Statements中的表述必须是布尔型的,switch中case必须用goto(spaghetti code)或break跳出 下面是for循环中什么都

ESLQ基础知识实践——实践一

1.声明变量,设置变量值(解析XML格式消息,IBM推荐使用XMLNSC,而不推荐使用XML,如果对传入的消息不知道是何种格式,则要用BLOB进行解析,最大限度进行容错处理). DECLARE JMS_DATE CHAR; SET JMS_DATE=CURRENT_TIMESTAMP; SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Version  =  DATASPEC_TIPS_VER; 2.引用其他包下的函

安全测试2_Web前端知识学习

上次讲到安全的简介,这次就来简单的讲解下基本的前端知识(html.js.css(不作讲解),牛逼的请忽略!!! 1.Html简单概述: Html和Html DOM 2.Html字符实体(借用别人的,详细可以百度了解更多字符实体): 3.了解Html常见事件属性: onerror(在错误发生时运行的脚本).onload(页面结束加载之后触发).onclick(元素上发生鼠标点击时触发).onchange(在元素值被改变时运行的脚本).onfocus(当元素获得焦点时运行的脚本).oninput(当

转载一篇比较详细的讲解html,css的一篇文章,很长

转载自这里,转载请注明出处. DIV+CSS系统学习笔记回顾 第一部分 HTML 第一章 职业规划和前景 职业方向规划定位: web前端开发工程师 web网站架构师 自己创业 转岗管理或其他 web前端开发的前景展望: 未来IT行业企业需求最多的人才 结合最新的html5抢占移动端的市场 自己创业做老板 随着互联网的普及web开发成为企业的宠儿和核心 web职业发展目标: 第一.梳理知识架构 负责内容的HTML 负责外观的css(层叠样式表) 负责行为的js ps切图 第二.分解目标(起步阶段.