国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

IOS開發--網絡篇-->Block簡介

2019-11-14 19:28:37
字體:
來源:轉載
供稿:網友

1、Blocks簡介

Block字面意思就是代碼塊 iOS4.0、Mac OS X 10.6開始Apple引入的特性

Block是Objective C語言中的對象 但是與NSObject有所區別 Block是特殊的Objective C對象

Block 對象提供了一個使用 C 語言和 C 派生語言(如 Objective-C 和 C++)來創建表達式作為一個特別的函數。在其他語言和環境中,一個block對象有時候被稱為“閉包(closure)”。在這里,它們通常被口語化為”塊(blocks)”,除非在某些范圍它們容易和標準 C 表達式的塊代碼混淆。

對于閉包(closure),有很多定義,其中閉包就是能夠讀取其它函數內部變量的函數

“^”符號可以稱為caret ['kær?t] 也叫脫字符 插入符 

 

 

返回值(^塊對象名稱)(參數列表類型) = ^(參數列表){塊對象中的代碼};

 

2、用處

1)簡單的回調過程,不用再實現并調用某個函數 (UIView動畫)

2)代碼簡潔,減少冗余代碼

3)與GCD結合使用 爽爆了 

使用:UIView動畫、PResentViewController、ASI 

 

3、聲明和創建Block

聲明Block引用 無參無返回 無參有返回 有參無返回 有參有返回

定義Block

使用Block

typedef聲明 簡稱typedef 為現有類型創建一個新的名字,或稱為類型別名,在結構體定義,還有一些數組等地方都會用到 

返回值或參數為Block的

snippet 代碼片段

4、Block對變量存取管理

1)局部變量

局部變量,在Block中只讀。Block定義時copy變量的值,在Block中作為常量使用,所以即使變量的值在Block外改變,也不影響它在Block中的值

 

2)__Block修飾的變量

如果要在block內修改block外聲明的局部變量,那么一定要對該變量加__block標記

 

3)Static修飾符的或全局變量

因為全局變量或靜態變量在內存中的地址是固定的,Block在讀取該變量值的時候是直接從其所在內存讀出,獲取到的是最新值,而不是在定義時copy的常量.

 Block變量,被__Block修飾的變量稱作Block變量。 基本類型的Block變量等效于全局變量或靜態變量 但對象的block變量不會

 

5、Block的內存管理

非ARC下

Block是默認建立在棧上, 所以如果離開方法作用域, Block就會被丟棄

Block的copy、retain、release操作  不同于NSObject的copy、retain、release操作:

只要實現一個對周圍變量沒有引用的Block,就會顯示為是NSGlobalBlock

如果其中加入了對局部變量的引用,就是NSStackBlock

如果你對一個NSStackBlock對象使用了Block_copy()或者發送了copy消息,就會得到NSMallocBlock

 

1)NSGlobalBlock:retain、copy、release操作都無效

2)NSStackBlock:retain、release操作無效,必須注意的是,NSStackBlock在函數返回后,Block內存將被回收,即使retain也沒用。

容易犯的錯誤是[mutableAarry addObject:stackBlock],(補:在ARC中不用擔心此問題,因為ARC中會默認將實例化的Block拷貝到堆上)在函數出棧后,從mutableAarry中取到的stackBlock已經被回收,變成了野指針。

正確的做法是先將[stackBlock copy]到堆上,然后加入數組:[mutableAarry addObject:[[stackBlock copy] autorelease]]。支持copy,copy之后生成新的NSMallocBlock類型對象。

3)NSMallocBlock支持retain、release,雖然retainCount始終是1,但內存管理器中仍然會增加、減少計數。copy之后不會生成新的對象,只是增加了一次引用,類似retain;

4)Block_copy與copy等效,Block_release與release等效;

5)對Block不管是retain、copy、release都不會改變引用計數retainCount,retainCount始終是1

6)盡量不要對Block使用retain操作,不方便管理。

Block的使用:UIView動畫、presentViewController、ASI

 

6、Block對objc對象的內存管理

staticObj、globalObj、instanceObj、localObj、blockObj多種類型obj對象

主要是block被copy時其塊中用到的變量的引用計數

1)非ARC

globalObj和staticObj在內存中的位置是確定的,所以Block copy時引用計數不會改變。

instanceObj在Block copy時并沒有直接讓instanceObj對象本身引用計數加1,但卻讓self引用計數加1。所以在Block中可以直接讀寫instanceObj變量。 

localObj在Block copy時,系統自動增加其引用計數

blockObj在Block copy時,引用計數也不會改變

使用__block避免循環引用 __block 類 *對象 = self

 

void(^block)(void)= ^{

[blockSelf doSomething];

};

 

7、循環引用retain cycle

循環引用指兩個對象相互強引用了對方,即retain了對方,從而導致誰也釋放不了誰的內存泄露問題。如聲明一個delegate時一般用assign而不能用retain或strong,因為你一旦那么做了,很大可能引起循環引用

 

釋放second 在fist delloc中釋放 fist的delloc什么時候執行呢 ?

fist引用計數為0時執行 ,然而現在即便是將fist從window.rootViewController上卸載下來 即釋放一次 卻發現second還保留著first的一次引用 到頭來還是要釋放second 形成了delegate版本的retain cycle 即循環引用

 

釋放_pBlock 在viewController delloc中釋放 delloc什么時候執行呢?

viewController引用計數為0時執行 ,然而現在即便是將viewController從window.rootViewController上卸載下來 即釋放一次 卻發現_pBlock還保留著viewController的一次引用 到頭來還是要釋放_pBlock 形成了block版本的retain cycle 即循環引用

 

Block的內存管理

ARC下

在ARC下, 以下幾種情況, Block會自動被從棧復制到堆:

1.被執行copy方法

2.作為方法返回值

3.將Block賦值給附有__strong修飾符的id類型的類或者Blcok類型成員變量時

4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中傳遞的時候.

 

Block中的對象的內存管理

ARC下

只有在使用local變量時,block會復制指針,且強引用指針指向的對象一次。其它如全局變量、static變量、block變量等,block不會拷貝指針,只會強引用指針指向的對象一次。

block的循環引用,因為block在拷貝到堆上的時候,會retain其引用的外部變量,那么如果block中如果引用了它的宿主對象,那很有可能引起循環引用。如:self.myblock = ^{[self doSomething];};

使用__weak避免循環引用

 

Tips:

內存主要分為

1.棧 - 由編譯器自動分配釋放  里面的變量通常是局部變量 函數參數等

2.堆 - 一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收 alloc

3.全局區(靜態區 static),全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。- 程序結束釋放 static

People *p;  People *p2 = nil;

4.另外還有一個專門放常量的地方。- 程序結束釋放  NSString *lastName = @“xue”;

lastName = @“dkjs”;

5、方法區

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 碌曲县| 乐业县| 赫章县| 饶河县| 白河县| 泸溪县| 蒙阴县| 荃湾区| 大埔县| 石河子市| 云霄县| 彭山县| 商南县| 石景山区| 渑池县| 和林格尔县| 景泰县| 裕民县| 卢氏县| 静宁县| 越西县| 牙克石市| 赣州市| 抚松县| 多伦县| 长葛市| 元氏县| 隆尧县| 旬邑县| 凤山县| 古丈县| 安宁市| 犍为县| 团风县| 江门市| 镇巴县| 开鲁县| 胶南市| 松潘县| 什邡市| 堆龙德庆县|