[個(gè)人博客搬運(yùn)]Objective-C的Block使用技巧

這周給大家分享的iOS知識(shí)算是蠻有意思的朴皆,用寫Java方法調(diào)用的語(yǔ)法來寫Objective-C帕识。沒有什么高大上的技術(shù),有的只是Block的使用技巧遂铡。前些天在讀這篇RAC源碼解析的文章 的時(shí)候肮疗,聯(lián)想到了Masonry/BlocksKit兩個(gè)三方框架,它們?nèi)即罅渴褂玫搅薆lock扒接,其中就有類似Java語(yǔ)法來寫Objective-C的例子伪货。

首先我們來看看普通的Block是什么樣的:

int (^myBlock1) (int, int) = ^(int a, int b) {
return a + b;
};

int s = myBlock1(1, 2);
NSLog(@"s = %i", s);

上面定義了一個(gè)名字叫做myBlock1的block,它接受兩個(gè)int類型的參數(shù)钾怔,并且返回int超歌。
而Masonry這個(gè)框架中,它的Block是這樣的:
[view makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view);
make.top.equalTo(self.view.top).offset(40);
make.bottom.equalTo(self.view.bottom).offset(-20);
make.width.equalTo(self.view.width).multipliedBy(0.8);
}];
我們看到其中的
make.width.equalTo(self.view.width).multipliedBy(0.8);
非常類似Java中的方法調(diào)用的寫法蒂教。
我們來研究下如何實(shí)現(xiàn)以上這種寫法。
首先我們定義一個(gè)Student對(duì)象脆荷,它由兩個(gè)方法play和study凝垛。
我們希望外部是這么調(diào)用它的:

Student *student = [[Student alloc] init];
student.study().play().study().play();
以前在寫Java解析XML的代碼時(shí),我經(jīng)常寫到node.setText("xxx").setAttribute("xxx")蜓谋。這種方法調(diào)用的關(guān)鍵在于方法調(diào)用完會(huì)返回一個(gè)調(diào)用者對(duì)象梦皮,受此啟發(fā),我們可以在發(fā)送消息時(shí)返回發(fā)送消息的sender桃焕。而在iOS中是使用方括號(hào)進(jìn)行消息發(fā)送剑肯,如果要加()則需要使用block。
因此我們有:

  • (Student *(^)())study
    {
    return ^() {
    NSLog(@"study");
    return self;
    };
    }

其中观堂,Student *(^)()表示一種Block類型让网,該Block不接受任何參數(shù),返回類型為Student师痕。
demo中的
student.study 等價(jià)于 [student study]
student.study() 等價(jià)于 student study
相當(dāng)于拿到返回的Block并直接執(zhí)行溃睹,繼續(xù)返回self,即student對(duì)象胰坟,因此可以繼續(xù)調(diào)用student對(duì)象方法

那有參數(shù)的情況是什么樣的呢因篇?我們想要這樣調(diào)用:
student.study().play(@"Dota").study().play(@"Pokemon”);

輸出:

2015-09-13 22:30:07.858 TestLinkedBlock[1478:27604] study
2015-09-13 22:30:07.858 TestLinkedBlock[1478:27604] play Dota
2015-09-13 22:30:07.858 TestLinkedBlock[1478:27604] study
2015-09-13 22:30:07.859 TestLinkedBlock[1478:27604] play Pokemon

既然點(diǎn)語(yǔ)法只支持沒有參數(shù)的方法,那我們可以試試把參數(shù)放在Block中:

  • (Student *(^)(NSString *gameName))play
    {
    return ^(NSString *gameName) {
    NSLog(@"play %@", gameName);
    return self;
    };
    }
    這樣的話,play方法就返回一個(gè)Block竞滓,它接受一個(gè)NSString *類型的參數(shù)咐吼,與調(diào)用方式非常吻合。

我們?cè)賮砜纯碝asonry中的用法:
make.width.equalTo(self.view.width).multipliedBy(0.8);
它的源碼是這樣的:

  • (MASConstraint * (^)(CGFloat))multipliedBy {
    return ^id(CGFloat multiplier) {
    for (MASConstraint *constraint in self.childConstraints) {
    constraint.multipliedBy(multiplier);
    }
    return self;
    };
    }
    返回一個(gè)Block商佑,該Block接受一個(gè)CGFloat锯茄,返回自身類型,從而實(shí)現(xiàn)鏈?zhǔn)降腂lock語(yǔ)法莉御。

最后我們嘗試在UIKit上做一些Extension:
我們想要這樣調(diào)用view來設(shè)置它的一些基本屬性:
UIView *view = [[UIView alloc] init];
[self.view addSubview:view];
view.ff_setFrame(CGRectMake(20, 20, 20, 20)).ff_setBackgroundColor([UIColor redColor]);
方法也很簡(jiǎn)單:

  • (UIView *(^)(CGRect))ff_setFrame
    {
    return ^(CGRect rect) {
    self.frame = rect;
    return self;
    };
    }

  • (UIView *(^)(UIColor *))ff_setBackgroundColor
    {
    return ^(UIColor *color) {
    self.backgroundColor = color;
    return self;
    };
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撇吞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子礁叔,更是在濱河造成了極大的恐慌牍颈,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琅关,死亡現(xiàn)場(chǎng)離奇詭異煮岁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涣易,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門画机,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人新症,你說我怎么就攤上這事步氏。” “怎么了徒爹?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵荚醒,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我隆嗅,道長(zhǎng)界阁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任胖喳,我火速辦了婚禮泡躯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丽焊。我一直安慰自己较剃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布技健。 她就那樣靜靜地躺著重付,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凫乖。 梳的紋絲不亂的頭發(fā)上确垫,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天弓颈,我揣著相機(jī)與錄音,去河邊找鬼删掀。 笑死翔冀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的披泪。 我是一名探鬼主播纤子,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼款票!你這毒婦竟也來了控硼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤艾少,失蹤者是張志新(化名)和其女友劉穎卡乾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缚够,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幔妨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谍椅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片误堡。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖雏吭,靈堂內(nèi)的尸體忽然破棺而出锁施,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嗜暴,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜婚温,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一描焰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栅螟,春花似錦荆秦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至吃媒,卻和暖如春瓤介,著一層夾襖步出監(jiān)牢的瞬間吕喘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工刑桑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氯质,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓祠斧,卻偏偏與公主長(zhǎng)得像闻察,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子琢锋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • (一)Masonry介紹 Masonry是一個(gè)輕量級(jí)的布局框架 擁有自己的描述語(yǔ)法 采用更優(yōu)雅的鏈?zhǔn)秸Z(yǔ)法封裝自動(dòng)布...
    木易林1閱讀 2,334評(píng)論 0 3
  • Masonry是一個(gè)輕量級(jí)的布局框架辕漂,擁有自己的描述語(yǔ)法,采用更優(yōu)雅的鏈?zhǔn)秸Z(yǔ)法封裝自動(dòng)布局吴超,簡(jiǎn)潔明了并具有高可讀性...
    3dcc6cf93bb5閱讀 1,765評(píng)論 0 1
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉钉嘹,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評(píng)論 0 9
  • 7月,俄羅斯探險(xiǎn)家謝爾蓋?阿納夫被迫將他的直升飛機(jī)丟棄在加拿大和格陵蘭島之間的冰域烛芬。以下是他自述的兩天經(jīng)歷...
    譯嘉閱讀 1,398評(píng)論 0 0
  • 界面如下 里面按鈕的布局思路就是先把第一個(gè)按鈕布局好 再布局第二個(gè)的時(shí)候判斷 后面的寬度是否能夠放得下,能放得下就...
    大墻66370閱讀 866評(píng)論 7 9