OC語言瘋狂講義學習筆記
1、關於nil和Nil及NULL的區別:
nil: A null pointer to an Objective-C object. ( #define nil ((id)0) ) nil 是一個物件值。
Nil: A null pointer to an Objective-C class.
NULL: A null pointer to anything else. ( #define NULL ((void *)0) ) NULL是一個通用指標(泛型指標)。
NSNull: A class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
[NSNull null]: The singleton instance of NSNull.
[NSNull null]是一個物件,他用在不能使用nil的場合。
2、避免使用殭屍物件的方法
為了防止不小心呼叫了殭屍物件,可以將物件賦值nil(物件的空值)

3、物件的記憶體洩露
4、@property 引數
記憶體管理相關引數:
5、@class的使用
作用
可以簡單地引用一個類
#### 簡單使用
@class Dog; //類的引入
僅僅是告訴編譯器: Dog是一個類; 並不會包含Dog這個類的所有內容
具體使用
在.h檔案中使用@class引用一個類 在.m檔案中使用#import包含這個類的.h檔案
通常引用一個類有兩種辦法:
一種是通過#import方式引入;另一種是通過@class引入; 這兩種的方式的區別在於:
1)#import方式會包含被引用類的所有資訊,包括被引用類的變數和方法;@class方式只是告訴 編譯器在A.h檔案中 B *b 只是類的宣告,具體這個類裡有什麼資訊,這裡不需要知道,等實現文 件中真正要用到時,才會真正去檢視B類中資訊;
2)使用@class方式由於只需要只要被引用類(B類)的名稱就可以了,而在實現類由於要用到被 引用類中的實體變數和方法,所以需要使用#import來包含被引用類的標頭檔案;
3)通過上面2點也很容易知道在編譯效率上,如果有上百個標頭檔案都#import了同一 個檔案,或 者這些檔案依次被#improt(A->B, B->C,C->D…),一旦最開始的標頭檔案稍有改動,後面引用到這 個檔案的所有類都需要重新編譯一遍,這樣的效率也是可想而知的,而相對來 講,使用@class方 式就不會出現這種問題了;
所以:我們實際開發中儘量在.h標頭檔案中使用@class
4)對於迴圈依賴關係來說,比方A類引用B類,同時B類也引用A類,B類的程式碼:
作用上的區別
import會包含引用類的所有資訊(內容), 包括引用類的變數和方法 @class僅僅是告訴編譯器有這麼一個類, 具體這個類裡有什麼資訊, 完全不知
效率上的區別
如果有上百個標頭檔案都#import了同一個檔案,或者這些檔案依次被#import,那麼一旦最開始的頭 檔案稍有改動,後面引用到這個檔案的所有類都需要重新編譯一遍 , 編譯效率非常低 相對來講,使用@class方式就不會出現這種問題了
6、迴圈引用
迴圈retain的場景
比如A物件retain了B物件,B物件retain了A物件 迴圈retain的弊端 這樣會導致A物件和B物件永遠無法釋放
迴圈retain的解決方案
當兩端互相引用時,應該一端用retain、一端用assign
7、NSString 類的記憶體管理問題
1)、NSString 等Foundation框架中類的記憶體管理
先看看以下這幾種寫法:
NSString *testStr1 = @”a”;
NSString *testStr2 = [NSString stringWithString:@”a”];
NSString *testStr3 = [NSString stringWithFormat:@”b”];
NSString *testStr4 = [[NSString alloc] initWithString:@”c”];
NSString *testStr5 = [[NSString alloc] initWithFormat:@”d”];
NSString *testStr6 = [[NSString alloc] init];
NSLog(@”testStr1 ->%p”,testStr1);
NSLog(@”testStr2 ->%p”,testStr2);
NSLog(@”testStr3 ->%p”,testStr3);
NSLog(@”testStr4 ->%p”,testStr4);
NSLog(@”testStr5 ->%p”,testStr5);
NSLog(@”testStr6 ->%p”,testStr6);
通過對比地址可以看到,從上可以看出,testStr1,testStr2,testStr4都是在一個記憶體區域,也 就是常量記憶體區,
1---> NSString *str = [[NSString alloc] initWithString:@"ABC"];
2---> str = @"123";
3---> [str release];
4---> NSLog(@"%@",str);
首先,我們們先對這段程式碼進行分析。
第一句 宣告瞭一個NSString型別的例項 str, 並將其初始化init後賦值為@”ABC” 第二行,將str的指標指向了一個常量@”123”。 理論上講在第一行初始化的@”ABC”沒有任何任何 指標指向了。 所以造成了記憶體洩露
然後第三行, 將str的引用計數-1
第四行輸出str的值 為123.
首先回答為什麼不會崩潰, 因為第三行的release 實際上是release了一個常量@”123” 而作為 常量,其預設的引用計數值是很大的(100k+)
NSLog(@”retainCount = %tu”,[@”123” retainCount]);
最終的輸出值會是一個很大很大的數。 所以單單一個release是不會將其釋放掉的。
然後再回答這樣會不會造成記憶體洩露。
其實…………理論上講 會!
但是實際上,Objective-C對NSString型別有特殊照顧。所有的NSString的引用計數器預設初始值 都會非常非常大。
2)、危險的用法
while ([a retainCount] > 0) {
[a release];
}
如果執行結果正確,那麼這是多麼幸運的一個人啊!
8、自動釋放池及autorelease介紹
自動釋放池
(1)在iOS程式執行過程中,會建立無數個池子,這些池子都是以棧結構(先進後出)存在的。 (2)當一個物件呼叫autorelease時,會將這個物件放到位於棧頂的釋放池中
自動釋放池的建立方式
(1)iOS 5.0以前的建立方式
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
`````````````````
[pool release];//[pool drain];用於mac
(2)iOS5.0以後
@autoreleasepool
{//開始代表建立自動釋放池
·······
}//結束代表銷燬自動釋放池
autorelease
是一種支援引用計數的記憶體管理方式
它可以暫時的儲存某個物件(object),然後在記憶體池自己的排幹(drain)的時候對其中的每個 物件傳送release訊息 注意,這裡只是傳送release訊息,如果當時的引用計數(reference-counted)依然不為0,則該 物件依然不會被釋放。可以用該方法來儲存某個物件,也要注意儲存之後要釋放該物件。
為什麼會有autorelease?
(1)不需要再關心物件釋放的時間
(2)不需要再關心什麼時候呼叫release
autorelease何時釋放?
對於autorelease pool本身,會在如下兩個條件發生時候被釋放
1)手動釋放Autorelease pool
2)Runloop結束後自動釋放
對於autorelease pool內部的物件
在引用計數的retain == 0的時候釋放。release和autorelease pool 的 drain都會觸發retain– 事件。
9、Block
一、靜態變數和全域性變數 在加和不加 __block都會直接引用變數地址。也就意味著可以修
改變數的值。在沒有加__block 引數的情況下。
• 全域性block和棧block區別為是否引用了外部變數,堆block則是對棧block copy得來。對全域性block
copy 不會有任何作用,返回的依然是全域性block。
二, 常量變數(NSString *a = @”hello”;a 為常量變數,@“hello”為常量。)—–不 加__block型別 block 會引用常量的地址(淺拷貝)。加__block型別 block會去引用常量變 量(如:a變數,a = @”abc”.可以任意修改a 指向的內容。)的地址。
相關文章
- 《瘋狂Kotlin講義》讀書筆記4——流程控制Kotlin筆記
- 瘋狂android講義目錄Android
- 瘋狂Java講義第3版PDFJava
- 瘋狂學習——DP!
- 《瘋狂Kotlin講義》讀書筆記6——函式和Lambda表示式Kotlin筆記函式
- Go語言核心36講(新年彩蛋)--學習筆記Go筆記
- Go語言核心36講(導讀)--學習筆記Go筆記
- 瘋狂Java程式設計師的基本素養學習筆記Java程式設計師筆記
- C 語言學習筆記筆記
- C語言學習筆記C語言筆記
- Go語言核心36講(Go語言進階技術十四)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十五)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十六)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十二)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十三)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術五)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術一)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術二)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術三)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術四)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術八)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術九)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十)--學習筆記Go筆記
- Go語言核心36講(Go語言進階技術十一)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識一)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識二)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識三)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識四)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識五)--學習筆記Go筆記
- Go語言核心36講(Go語言基礎知識六)--學習筆記Go筆記
- 瘋子C語言筆記 (string)C語言筆記
- Go語言核心36講(Go語言實戰與應用七)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用八)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用二)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用四)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用五)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用十七)--學習筆記Go筆記
- Go語言核心36講(Go語言實戰與應用十八)--學習筆記Go筆記