iOS開發(fā)--當Block黔宛、代理、通知遇到女朋友

什么是Block?

為什么使用Block?

怎么使用Block?

本文將從這三個問題入手來逐漸了解Block雳殊。

本文使用的范例傳送門:https://github.com/Elbertz/ZDXBlockStudy


什么是Block橘沥?

首先我們先來觀察一下block的書寫格式

a (^b)(c,d)=^(c name1,d name2){};

a:Block的返回值類型,可以為空(void);

b:Block對象名稱夯秃,可以理解為變量名座咆;

^:塊的語法標記,聲明b為一個Block對象;

c:第一個參數(shù)類型

d:第二個參數(shù)類型

name1仓洼,name2:參數(shù)名;

{}:Block代碼塊的主題部分介陶。

有人認為Block是代碼塊,以閉包形式存在的一段代碼良好的獨立性和可交互性色建;

也有人把Block當作OC的匿名函數(shù)哺呜,可以很好的傳遞參數(shù);

還有人認為Block是一種特殊的數(shù)據(jù)類型箕戳,創(chuàng)建的Block對象可以更好的被上下文所調(diào)用某残;

還有一群人国撵,他們覺得Block就是Block,盲目而片面的定義掩蓋了它簡易精妙的使用玻墅,因此他們從使用場景中描述Block是什么介牙。

為什么使用Block?

Block作為參數(shù)澳厢、返回值可以更便捷的在各個場景間傳遞环础;

Block作為回調(diào)可以廣泛的使用在多線程GCD、動畫剩拢、排序的情形下线得;

下面是Block的基礎(chǔ)使用,對Block的使用思路清晰的童鞋可以通過下面的2個案例進行深度學(xué)習(xí):

Block實現(xiàn)各種排序:https://github.com/JiongXing/JXSort

AFNetworking:https://github.com/AFNetworking/AFNetworking

怎么使用Block徐伐?

在使用之前贯钩,我們先對Block在ARC和MRC環(huán)境下使用的基礎(chǔ)知識點普及:

ARC:系統(tǒng)會幫你管理你自己創(chuàng)建的對象的內(nèi)存

MRC:你需要管理你自己創(chuàng)建的對象的內(nèi)存

當你創(chuàng)建一個新的project時默認是ARC環(huán)境,你可以在Build Setting下關(guān)閉自動引用記數(shù)切換到MRC環(huán)境呵晨。

為什么使用copy來修飾Block魏保?

使用copy可以將Block從棧上轉(zhuǎn)移到堆上

MRC下,默認是棧上為了控制Block生命周期摸屠,需要將其copy的堆上谓罗,不可以用reatin代替。 ARC下大多數(shù)情況默認是在堆上季二,但是因為一般遵循傳統(tǒng)檩咱,會寫上copy,但是可以用strong來代替胯舷。

ARC下需不需要對Block進行手動copy刻蚯?

不用手動copy的情形?

1.當 Block 被強引用時桑嘶。

2.系統(tǒng)的 API 中帶有 usingBlock 時炊汹。

3.Block 作為函數(shù)返回值。

用手動copy的情形逃顶?

當block 作為函數(shù)參數(shù)的時候讨便,在 arc 下我們自定義的Block 要寫上 copy。

注意:copy的特點

1.如果原來在棧上以政,通過copy霸褒,被復(fù)制到堆上。

2.如果原來在全局數(shù)據(jù)區(qū)盈蛮,不會發(fā)生改變

3.如果在堆區(qū):其引用計數(shù)加1

在Block使用過程中废菱,如何避免循環(huán)引用?

ARC情況下

1.如果用copy修飾Block,該Block就會存儲在堆空間殊轴。則會對Block的內(nèi)部對象進行強引用衰倦,導(dǎo)致循環(huán)引用。內(nèi)存無法釋放梳凛。

2.如果用weak修飾Block耿币,該Block就會存放在検嵝樱空間韧拒。不會出現(xiàn)循環(huán)引用問題。

MRC情況下

用copy修飾后十性,如果要在Block內(nèi)部使用對象叛溢,則需要進行(__block typeof(Target) blockTarget = Target )處理。在Block里面用blockTarget進行操作劲适。

__block在MRC下有兩個作用

1. 允許在Block中訪問和修改局部變量

2. 禁止Block對所引用的對象進行隱式retain操作

__block在ARC下只有一個作用

1. 允許在Block中訪問和修改局部變量

__weak可以避免在ARC下Block造成循環(huán)引用

使用場景楷掉?

標準范式:

// 1.使用typedef定義Block類型

typedef int(^MyBlock)(int, int);

// 2.定義一個形參為Block的OC函數(shù)

- (void)useBlockForOC:(MyBlock)aBlock

{

NSLog(@"result = %d", aBlock(300,200));

}

// 3.聲明并賦值定義一個Block變量

MyBlock addBlock = ^(int x, int y){

return x+y;

};

// 4.以Block作為函數(shù)參數(shù),把Block像對象一樣傳遞

[self useBlockForOC:addBlock];

// 將第3點和第4點合并一起,以內(nèi)聯(lián)定義的Block作為函數(shù)參數(shù)

[self useBlockForOC:^(int x, int y){

return x+y;

}];

情景一:傳遞參數(shù)

viewController 控制器1,testViewController 控制器2霞势,控制器1跳轉(zhuǎn)到控制器2烹植,然后在控制器2觸發(fā)事件回調(diào)修改控制器1的對應(yīng)控件的背景色為紅色?

testViewController

typedef void (^myBlock)(UIColor* color);

@property (nonatomic,copy)myBlock block1;

UIColor *color = [UIColor redColor];

//給Block傳入?yún)?shù)color

self.block1(color);

[self.navigationController popViewControllerAnimated:YES];

viewController

//plan1

testViewController *testVC = [[testViewController alloc]init];

testVC.block1 = ^(UIColor *color){

label1.backgroundColor = color;

};

[self.navigationController pushViewController:testVC animated:YES];

//plan2

//當block中使用了self時愕贡,需要對self添加__weak關(guān)鍵字草雕,避免循環(huán)調(diào)用

__weak typeof(self) weakself = self;//等價于下一行代碼

//__weak UIViewController* weakself = self;

testViewController *testVC = [[testViewController alloc]init];

testVC.block1 = ^(UIColor *color){

weakself.label2.backgroundColor = color;

};

[self.navigationController pushViewController:testVC animated:YES];

當在Block代碼塊中使用了self,請注意要避免循環(huán)應(yīng)用固以。

Q:說好的女朋友呢墩虹? 看好了,女朋友的問題來了

一天憨琳,你的女朋友逛淘寶的時候?qū)δ阏f诫钓,這個包包好漂亮,買給我嘛篙螟?么么噠菌湃! 面對糖衣炮彈轟擊對你默默的登錄了自己的支付寶賬號點下了確認支付的按鈕。

女朋友想買的東西委托給你去買遍略,這是代理模式的典型案例惧所,同樣也可用block實現(xiàn)。

1)代理模式實現(xiàn)

girlFriends *gf = [girlFriends shareInstance];

gf.delegate = self;

[gf buyALadiesBackpackForMe];

2)使用Block實現(xiàn)

__weak typeof(self) weakself = self;

//block先賦值墅冷,再使用

girlFriends *gf = [girlFriends shareInstance];

//[gf buyAnotherLadiesBackpackForMe]; //wrong write place

gf.buyBlock = ^(NSString *goods){

NSString *tempStr = [NSString stringWithFormat:@"%@??????",goods];

[weakself.label4 setText:tempStr];

};

[gf buyAnotherLadiesBackpackForMe];

if (timer.isValid == YES) {

[timer invalidate];

}

3.使用通知模式實現(xiàn)

//tips:先注冊觀察者纯路,再發(fā)送通知

girlFriends *gf = [girlFriends shareInstance];

//[gf buyAnyoneLadiesBackpackForMe];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(buyLVAction:) name:@"buybag" object:nil];

[gf buyAnyoneLadiesBackpackForMe];

-(void)dealloc{

//記得釋放通知的觀察者對象

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"buybag" object:nil];

}

情景二:Block作為參數(shù)

girlFriends *gf = [girlFriends shareInstance];

[gf buyMoreLadiesBackpackForMe:^float(int loveNumber) {

//

NSLog(@"520");

float result = 520+(float)loveNumber/10000;

NSLog(@"%.4f",(float)loveNumber/10000);

NSString *tempStr = [NSString stringWithFormat:@"%.4f??????",result];

[_label6 setText:tempStr];

return result;

}];

if (timer.isValid == YES) {

[timer invalidate];

}

girlFriends.m

-(void)buyMoreLadiesBackpackForMe:(myLoveBlock2)ablock{

float result = ablock(1314);

NSLog(@"%.4f",result);

}

情景三:Block作為返回值

通過遞歸調(diào)用來體現(xiàn)以Block作為返回值的函數(shù)的調(diào)用和實現(xiàn)

調(diào)用

[self digui:3];

實現(xiàn)

- (int)digui:(int)number{

if (number <= 2 && number > 0) {

return number;

} else {

int tempResult = [self digui:number-1];

return number*tempResult;

}

}

調(diào)用

gf.setupTab5(3);

實現(xiàn)

- (int(^)(int))setupTab5

{

__weak typeof (self)weakSelf = self;

int(^block)(int) = ^(int a){

_recursiveResult2 *= a;

NSLog(@”%d – %d”, _recursiveResult2,a);

if (a>1) {

weakSelf.setupTab5(a-1);

//weakSelf setupTab5;

}

return _recursiveResult2;

};

return block;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市寞忿,隨后出現(xiàn)的幾起案子驰唬,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叫编,死亡現(xiàn)場離奇詭異辖佣,居然都是意外死亡,警方通過查閱死者的電腦和手機搓逾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門卷谈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人霞篡,你說我怎么就攤上這事世蔗。” “怎么了朗兵?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵污淋,是天一觀的道長。 經(jīng)常有香客問我余掖,道長寸爆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任盐欺,我火速辦了婚禮赁豆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冗美。我一直安慰自己魔种,他們只是感情好,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布墩衙。 她就那樣靜靜地躺著务嫡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪漆改。 梳的紋絲不亂的頭發(fā)上心铃,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機與錄音挫剑,去河邊找鬼去扣。 笑死,一個胖子當著我的面吹牛樊破,可吹牛的內(nèi)容都是我干的愉棱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哲戚,長吁一口氣:“原來是場噩夢啊……” “哼奔滑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起顺少,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朋其,失蹤者是張志新(化名)和其女友劉穎王浴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梅猿,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡氓辣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了袱蚓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钞啸。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖喇潘,靈堂內(nèi)的尸體忽然破棺而出体斩,到底是詐尸還是另有隱情,我是刑警寧澤响蓉,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布硕勿,位于F島的核電站哨毁,受9級特大地震影響枫甲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扼褪,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一想幻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧话浇,春花似錦脏毯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赏寇,卻和暖如春吉嫩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嗅定。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工自娩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人渠退。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓忙迁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親碎乃。 傳聞我的和親對象是個殘疾皇子姊扔,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

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

  • 《Objective-C高級編程》這本書就講了三個東西:自動引用計數(shù)、block梅誓、GCD恰梢,偏向于從原理上對這些內(nèi)容...
    WeiHing閱讀 9,816評論 10 69
  • Block使用場景晨川,可以在兩個界面的傳值,也可以對代碼封裝作為參數(shù)的傳遞等删豺。用過GCD就知道Block的精妙之處共虑。...
    Coder_JMicheal閱讀 724評論 2 1
  • 前言 Blocks是C語言的擴充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,768評論 0 23
  • Block簡介(copy一段) Block作為C語言的擴展呀页,并不是高新技術(shù)妈拌,和其他語言的閉包或lambda表達式是...
    qui丶MyLove閱讀 427評論 0 0
  • 在2015年5月21日凌晨夢到這個故事的開頭,當時五點半爬起來把開頭寫下蓬蝶,只是直到現(xiàn)在才開始動手想著把它補成一個小...
    珊瑚赫閱讀 1,234評論 0 1