iOS 鏈式編程簡單的使用
鏈式編程-顧名思義,鏈式,連貫性為其主要特征,放在編程領(lǐng)域來講,說簡單點就是把一系列的代碼執(zhí)行動作串聯(lián)起來,不用單獨一個一個的執(zhí)行
在使用 Masonry 和 SDAutoLayout 框架實現(xiàn)自動布局的時候,進行了對比
Masonry:
[View mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(anotherView);
make.left.equalTo(anotherView);
make.width.mas_equalTo(@60);
make.height.mas_equalTo(@60);
}];
SDAutoLayout:
View.sd_layout
.leftSpaceToView(self.view, 10)
.topSpaceToView(self.view, 80)
.heightIs(130)
.widthRatioToView(self.view, 0.4);
相比較兩種實現(xiàn)方法來看,SDAutoLayout相對來說更簡單,代碼量更少,也更容易理解和使用!
這里說一下我對這兩個框架的一點理解
Masonry 和 SDAutoLayout 實現(xiàn)思路:鏈式編程思想。
鏈式編程
鏈式編程思想:是將多個操作(多行代碼)通過點號(.)鏈接在一起成為一句代碼,使代碼可讀性好。a(1).b(2).c(3)
鏈式編程特點:方法的返回值是block,block必須有返回值(本身對象),block參數(shù)(需要操作的值)
代表:Masonry框架、SDAutoLayout框架
鏈式編程另一個關(guān)鍵點--block:
Block的定義格式
返回值類型(^block變量名)(形參列表) = ^(形參列表) {
};
調(diào)用Block保存的代碼
block變量名(實參);
默認情況下,Block內(nèi)部不能修改外面的局部變量
Block內(nèi)部可以修改使用__block修飾的局部變量
Block的模式
1.無參數(shù)無返回值的Block
2.有參數(shù)無返回值的Block
3.有參數(shù)有返回值的Block
Block簡單用法舉例
無參數(shù)無返回值的Block
/**
* 無參數(shù)無返回值的Block
*/
-(void)func1{
/**
* void :就是無返回值
* emptyBlock:就是該block的名字
* ():這里相當于放參數(shù)。由于這里是無參數(shù),所以就什么都不寫
*/
void (^emptyBlock)() = ^(){
NSLog(@"無參數(shù),無返回值的Block");
};
emptyBlock();
}
有參數(shù)無返回值的Block
/**
* 調(diào)用這個block進行兩個參數(shù)相加
*
* @param int 參數(shù)A
* @param int 參數(shù)B
*
* @return 無返回值
*/
void (^sumBlock)(int ,int ) = ^(int a,int b){
NSLog(@"%d + %d = %d",a,b,a+b);
};
/**
* 調(diào)用這個sumBlock的Block,得到的結(jié)果是20
*/
sumBlock(10,10);
有參數(shù)有返回值的Block
/**
* 有參數(shù)有返回值
*
* @param NSString 字符串1
* @param NSString 字符串2
*
* @return 返回拼接好的字符串3
*/
NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){
return [NSString stringWithFormat:@"%@%@",str1,str2];
};
//調(diào)用logBlock,輸出的是 我是Block
NSLog(@"%@", logBlock(@"我是",@"Block"));
Block結(jié)合typedef使用
自己定義一個Block類型,用定義的類型去創(chuàng)建Block,更加簡單便捷。
這里舉一個例子 UIButton的鏈式編程實現(xiàn)
CHButton.h
//
// CHButton.h
// testDemo
//
// Created by 邵雄華 on 2017/4/13.
// Copyright ? 2017年 sxh. All rights reserved.
//
#import <UIKit/UIKit.h>
@class CHButton;
//typedef一個返回值為CHButton* 參數(shù)為NSString* 的名字為ChainButtonStringBlock的block,方便以后快速定義該類型block
typedef CHButton *(^ChainButtonStringBlock)(NSString *aName);
typedef CHButton *(^ChainButtonIntegerBlcok)(NSUInteger aNumber);
typedef CHButton *(^ChainButtonColorBlock)(UIColor *aColor);
typedef CHButton *(^ChainButtonFrameBlock)(CGRect aframe);
@interface CHButton : UIButton
- (ChainButtonStringBlock)imageName;
- (ChainButtonStringBlock)title;
- (ChainButtonIntegerBlcok)titleFont;
- (ChainButtonColorBlock)textColor;
- (ChainButtonFrameBlock)btnframe;
//該方法為工廠方法,能夠快速創(chuàng)建一個ChainButton,在一個參數(shù)為block的方法中一次性設(shè)置好你需要的ChainButton
+ (CHButton *)makeJJButton:(void (^)(CHButton *))block;
@end
CHButton.m
//
// CHButton.m
// testDemo
//
// Created by 邵雄華 on 2017/4/13.
// Copyright ? 2017年 sxh. All rights reserved.
//
#import "CHButton.h"
@implementation CHButton
- (ChainButtonStringBlock)imageName{
return ^CHButton *(NSString *aName){
[self setImage:[UIImage imageNamed:aName] forState:UIControlStateNormal];
NSLog(@"imageName");
return self;
};
}
- (ChainButtonStringBlock)title{
return ^CHButton *(NSString *aName){
[self setTitle:aName forState:UIControlStateNormal];
NSLog(@"title");
return self;
};
}
- (ChainButtonIntegerBlcok)titleFont{
return ^CHButton *(NSUInteger aNumber){
self.titleLabel.font = [UIFont systemFontOfSize:aNumber];
NSLog(@"titleFont");
return self;
};
}
- (ChainButtonColorBlock)textColor{
return ^CHButton *(UIColor *aColor){
[self setTitleColor:aColor forState:UIControlStateNormal];
NSLog(@"textColor = %@",aColor);
return self;
};
}
- (ChainButtonFrameBlock)btnframe{
return ^CHButton *(CGRect btnframe){
[self setFrame:btnframe];
return self;
};
}
+ (CHButton *)makeJJButton:(void (^)(CHButton *))block{
CHButton * button = [[CHButton alloc] init];
block(button);
return button;
}
@end
使用方法:利用工廠模式模式創(chuàng)建一個CHButton
[CHButton makeJJButton:^(CHButton *button) {
button.title(@"xixixi").imageName(@"abc").titleFont(20).textColor([UIColor orangeColor]).btnframe(CGRectMake(100, 100, 100, 100));
button.frame = CGRectMake(100, 250, 100, 100);
[self.view addSubview:button];
[button addTarget:self action:@selector(didClick:) forControlEvents:UIControlEventTouchUpInside];
}];
總結(jié)
鏈式編程要返回自身,每一個鏈式方法都必須返回明確的類型才能一直點下去,使用protocol或繼承都不行,必須在每一個方法的聲明時明確返回對象的類型。所以鏈式文件中不但有該類的方法聲明,也有父類的方法聲明。
后續(xù)會對更對的類進行鏈式的一種封裝,提高開發(fā)的效率。