iOS【Block-让代码更模块化】使用场景"保存代码","消息传值","参数使用"[封装工具类],"返回值"[链式编程]

1.保存代码

Block:在一个方法中定义,在另一个方法中调用 (不常用) 保存代码
场景:代码保存在模型中,tableView在点击cell的情况下,执行模型中的block代码
视图-模型-控制器...
步骤

  • 1:用tableViewController管理tableView,并设置数据源:
  • 2:模型定义block属性,标题属性,在控制器中拿到数据,并给模型赋值
  • 3模型的标题属性赋值给tableView的cell的标题属性
  • 4点击cell取出模型,判断block是否有值,执行模型中的block
@property (nonatomic ,strong) void(^block)();
@property (nonatomic ,strong) NSString *title;

- (void)viewDidLoad {
    [super viewDidLoad];

    // 打电话
    CellItem *item = [[CellItem alloc] init];
    item.title = @"打电话";
    item.block = ^{
        NSLog(@"打电话");
    };

    // 发短信
    CellItem *item1 = [[CellItem alloc] init];
    item1.title = @"发短信";
    item1.block = ^{
        NSLog(@"发短信");
    };

    // 发邮件
    CellItem *item2 = [[CellItem alloc] init];
    item2.title = @"发邮件";
    item2.block = ^{
        NSLog(@"发邮件");
    };
    _cellArr = @[item,item1,item2];
}

// 点击cell就会调用
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CellItem *item = self.cellArr[indexPath.row];

    if (item.block) {
        item.block();
    }
}

2.消息传值[同代理] // Block:在一个类中定义,在另一个类中调用(常用), -> 传值

传值:
A -> B 顺传:定义属性
B -> A 逆传:代理(block替换代理)

传值万能步骤:传给谁,只要拿到对方就能传值给他
  • 1.在接收事件对象h声明block属性
  • 2.在接收事件方法中给block属性赋值
  • 3.在处理事件对象方法中拿到接收事件对象并调用属性,且用闭包拿到属性变量,在闭包中使用属性变量
@interface ModalViewController : UIViewController
@property (nonatomic ,strong) void(^valueBlock)(NSString *value);
@end     //直接无法完成需求实现,传递消息给能拿到自己的对象
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event   //事件传递
{   if (_valueBlock) {  //能拿到本宝宝调用闭包,就请在闭包实现诉求
        _valueBlock(@"123");
    }
}
ModalViewController *modalVc = [[ModalViewController alloc] init];
    modalVc.valueBlock = ^(NSString *value){
        NSLog(@"接收到%@",value);
        //拿到属性了,在这里做坏事
    };

3.参数使用-[封装工具类]

CalculateManager *manager = [[CalculateManager alloc]init];//入手计算器
[manager calculate:^float(float result) {//用户打开/使用计算器
        result +=user_a_input_num;//用户拿掉计算器+一次输入
        result *=user_b_input_num;//用户拿掉计算器*一次输入
        return result; //用户按下等于,计算器内部需要知道结果,用来下一步操作
    }];
计算器内部构造
#import <Foundation/Foundation.h>
@interface CalculateManager : NSObject
/** 计算结果 */
@property (nonatomic, assign) float result;
//计算
- (void)calculate:(float(^)(float result))block;
@end
#import "CalculateManager.h"
@implementation CalculateManager
- (void)calculate:(float (^)(float))block
{//计算器响应用户的消息
    _result = block(_result);//计算器开始计算[传递参与计算的参数]-需要拿到用户输入-计算器储存结果[返回值float计算结果]
}
@end

程序执行步骤:

  • 1.入手计算器
  • 2.用户打开/使用计算器
  • 3.计算器响应用户的消息
  • 4.计算器开始计算
  • 5.需要拿到用户输入
  • 6计算器储存结果
自定义工具类,计算距离当前已经过去时间
/**
 *  @return 返回单例对象
 */
+ (instancetype)sharePublishedPassTime;

/** 计算结果 - passTimes_str */
@property (nonatomic, strong) NSString *passTimes_str;

/**
 *  [passTimes_str=当前时间-过去时间]
 *
 *  @param str_time      传入时间
 *  @param passTimes_str 过去了多长时间
 *
 *  @return 过去了多长时间
 */
- (NSString *)PublishedPassTimeWithTimeNSString:(NSString *)str_time result:(void(^)(NSString *passTimes_str))passTimes_str;

- (NSString *)PublishedPassTimeWithTimeNSString:(NSString *)str_time result:(void(^)(NSString *passTimes_str))passTimes_str
{

    //获得服务器返回时间[发布时间]
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd HH:mm";
    //    @"yyyy-MM-dd HH:mm:ss Z"; 完整例子 @"2015-06-29 07:05:26 +0000";
    NSDate *date = [formatter dateFromString:str_time];

    //获得当前的时间
    NSDate *now = [NSDate date];

    /** 计算时间差值 */
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendarUnit type = NSCalendarUnitYear |
    NSCalendarUnitMonth |
    NSCalendarUnitDay |
    NSCalendarUnitHour |
    NSCalendarUnitMinute |
    NSCalendarUnitSecond;
    NSDateComponents *cmps = [calendar components:type fromDate:date toDate:now options:0];

    if (cmps.year != 0) {
        _passTimes_str = [NSString stringWithFormat:@"%ld年前",cmps.year];
    }else if (cmps.month != 0){
        _passTimes_str = [NSString stringWithFormat:@"%ld月前",cmps.month];
    }else if (cmps.day != 0){
        _passTimes_str = [NSString stringWithFormat:@"%ld天前",cmps.day];
    }else if (cmps.hour != 0){
        _passTimes_str = [NSString stringWithFormat:@"%ld小时前",cmps.hour];
    }else if (cmps.hour != 0){
        _passTimes_str = [NSString stringWithFormat:@"%ld分钟前",cmps.minute];
    }else{
        _passTimes_str = @"刚刚";
    }

    passTimes_str(_passTimes_str);

    return _passTimes_str;
}

[[GLPublishedPassTime sharePublishedPassTime] PublishedPassTimeWithTimeNSString:item.create result:^(NSString *passTimes_str) {//在cell中使用模型属性set方法给属性时间字符串赋值
        self.create.text = passTimes_str;
    }];

static GLPublishedPassTime *_instance;
/** 返回单例 */
+ (instancetype)sharePublishedPassTime
{
    return [[self alloc]init];
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

程序执行步骤:

  • 1.cell中获得计算单例对象并调用对象方法
  • 2.计算时间差,并根据条件赋值字符串_passTimes_str
  • 3.调用到block,把字符串_passTimes_str传递给block参数,供外界使用
  • 4.外界cell拿到参数给cell的属性赋值
  • 5.执行完cell中的闭包代码块
  • 6工具类.对象方法返回字符串

4.返回值[链式编程]

需求:外界想只传递计算参数使用点语法[获取属性值],或者[计算修改某属性] 并且计算都封装在工具类
步骤1.外界如何使用,内部工具如何设计.

CalculateManager *mgr = [[CalculateManager alloc]init];
NSLog(@"%d",mgr.add(5).add(5).add(5).result);
#import <Foundation/Foundation.h>
@interface CalculateManager : NSObject
/** result */
@property (nonatomic, assign) int result;
- (CalculateManager *(^)(int value))add;
@end
#import "CalculateManager.h"
@implementation CalculateManager
-(CalculateManager *(^)(int))add
{
    return ^(int value){
        _result +=value;
        return self;
    };
}
@end

封装工具类:返回值中定义block并在block传入字符串参数,计算结果保存在工具类属性

self.create.text = [GLPublishedPassTime sharePublishedPassTime].passTime(item.create).passTimes_str;

/** 计算结果 - passTimes_str */
@property (nonatomic, strong) NSString *passTimes_str;

/**
 *  block中传入str_time发布时间,结果保存在passTimes_str属性中
 */
- (GLPublishedPassTime *(^)(NSString *str_time))passTime;

- (GLPublishedPassTime *(^)(NSString *))passTime
{
    return ^(NSString *str_time){

        //获得服务器返回时间[发布时间]
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd HH:mm";
        //    @"yyyy-MM-dd HH:mm:ss Z"; 完整例子 @"2015-06-29 07:05:26 +0000";
        NSDate *date = [formatter dateFromString:str_time];

        //获得当前的时间
        NSDate *now = [NSDate date];

        /** 计算时间差值 */
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSCalendarUnit type = NSCalendarUnitYear |
        NSCalendarUnitMonth |
        NSCalendarUnitDay |
        NSCalendarUnitHour |
        NSCalendarUnitMinute |
        NSCalendarUnitSecond;
        NSDateComponents *cmps = [calendar components:type fromDate:date toDate:now options:0];

        if (cmps.year != 0) {
            _passTimes_str = [NSString stringWithFormat:@"%ld年前",cmps.year];
        }else if (cmps.month != 0){
            _passTimes_str = [NSString stringWithFormat:@"%ld月前",cmps.month];
        }else if (cmps.day != 0){
            _passTimes_str = [NSString stringWithFormat:@"%ld天前",cmps.day];
        }else if (cmps.hour != 0){
            _passTimes_str = [NSString stringWithFormat:@"%ld小时前",cmps.hour];
        }else if (cmps.hour != 0){
            _passTimes_str = [NSString stringWithFormat:@"%ld分钟前",cmps.minute];
        }else{
            _passTimes_str = @"刚刚";
        }
        return self;
    };
}

/** 返回单例 */
+ (instancetype)sharePublishedPassTime
{
    return [[self alloc]init];
}

最后小结一下:block在开发中最长用的还是第二种,进行数据传值.对于第三和第四种使用场景,多使用在需要处理一些方法调用.像上述只是需要一个返回值,自定义工具类中用一个类方法就能搞定啦。

最后祝大家身体健康.再见

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容

  • 本文略为全面的介绍block的使用:block定义方式,block传值,block循环引用,block内存管理,b...
    王技术阅读 2,938评论 13 39
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,139评论 30 470
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,748评论 1 92
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,342评论 0 1