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在開發中最長用的還是第二種,進行數據傳值.對于第三和第四種使用場景,多使用在需要處理一些方法調用.像上述只是需要一個返回值,自定義工具類中用一個類方法就能搞定啦。

最后祝大家身體健康.再見

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文略為全面的介紹block的使用:block定義方式,block傳值,block循環引用,block內存管理,b...
    王技術閱讀 3,074評論 13 39
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,216評論 30 472
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,973評論 19 139
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,809評論 1 92
  • 2017.02.22 可以練習,每當這個時候,腦袋就犯困,我這腦袋真是神奇呀,一說讓你做事情,你就犯困,你可不要太...
    Carden閱讀 1,378評論 0 1