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 *)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 
@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 
@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在开发中最长用的还是第二种,进行数据传值.对于第三和第四种使用场景,多使用在需要处理一些方法调用.像上述只是需要一个返回值,自定义工具类中用一个类方法就能搞定啦。

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

你可能感兴趣的:(iOS【Block-让代码更模块化】使用场景"保存代码","消息传值","参数使用"[封装工具类],"返回值"[链式编程])