什麼是arc:
arc是ios 5推出的新功能,全稱叫 arc(automatic reference counting)。簡單地說,就是**中自動加入了retain/release,原先需要手動新增的用來處理記憶體管理的引用計數的**可以自動地由編譯器完成了。
該機能在 ios 5/ mac os x 10.7 開始匯入,利用 xcode4.2 可以使用該機能。簡單地理解arc,就是通過指定的語法,讓編譯器(llvm 3.0)在編譯**時,自動生成例項的引用計數管理部分**。有一點,arc並不是gc,它只是一種**靜態分析(static analyzer)工具。
變化:
通過一小段**,我們看看使用arc前後的變化點。
@inte***ce nonarcobject : nsobject
-(id)initwithname:(nsstring *)name;
@end
@implementation nonarcobject
-(id)initwithname:(nsstring *)newname
return self;
}
-(void)dealloc
@end
@inte***ce arcobject : nsobject
-(id)initwithname:(nsstring *)name;
@end
@implementation arcobject
-(id)initwithname:(nsstring *)newname
return self;
} @end
我們之前使用objective-c中記憶體管理規則時,往往採用下面的準則
而使用arc後,我們可以不需要這樣做了,甚至連最基礎的release都不需要了。
使用arc有什麼好處呢?
1、看到上面的例子,大家就知道了,以後寫objective-c的**變得簡單多了,因為我們不需要擔心煩人的記憶體管理,擔心記憶體洩露了
2、**的總量變少了,看上去清爽了不少,也節省了勞動力
3、**高速化,由於使用編譯器管理引用計數,減少了低效**的可能性
不好的地方:
關於第二點,由於 xcode4.2 中預設arc就是 on 的狀態,所以編譯舊**的時候往往有"automatic reference counting issue"的錯誤資訊。
這個時候,可以將專案編譯設定中的「objectice-c auto reference counteting」設為no。如下所示。
如果只想對某個.m檔案不適應arc,可以只針對該類檔案加上 -fno-objc-arc 編譯flags,如下圖。
arc基本規則:
由於arc並不是gc,並需要一些規則讓編譯器支援**插入,所以必須清楚清楚了這些規則後,才能寫出健壯的**。
objectivec物件:
objectivec中的物件,有強參照(strong reference)和弱參照(weak reference)之分,當需要保持其他物件的時候,需要retain以確保物件引用計數加1。物件的持有者(owner)只要存在,那麼該物件的強參照就一直存在。
物件處理的基本規則是
firstname作為」natsu」字串物件的最初持有者,是該nsstring型別物件的strong reference。
(s2)
這裡將firstname代入到aname中,即aname也成為了@」natsu」字串物件的持有者,對於該物件,aname也是strong reference。
(s3)
這裡,改變firstname的內容。生成新的字串物件」maki」。這時候firstname成為」maki」的持有者,而@」natsu」的持有者只有aname。每個字串物件都有各自的持有者,所以它們都在記憶體中都存在。
(s4)
追加新的變數othername, 它將成為@」maki」物件的另乙個持有者。即nsstring型別物件的strong reference。
(s5)
將othername代入到aname,這時,aname將成為@」maki」字串物件的持有者。而物件@」natsu」已經沒有持有者了,該物件將被破棄
弱參照:
與強參照方式同樣,firstname作為字串物件@」natsu」的持有者存在。即是該nsstring型別物件的strong reference。
(w2)
使用關鍵字__weak,宣告弱參照weakname變數,將firstname代入。這時weakname雖然參照@」natsu」,但仍是weak reference。即weakname雖然能看到@」natsu」,但不是其持有者。
(w3)
firstname指向了新的物件@」maki」,成為其持有者,而物件@」natsu」因為沒有了持有者,即被破棄。同時weakname變數將被自動代入nil。
引用關鍵字:
arc中關於物件的引用參照,主要有下面幾關鍵字。使用strong, weak, autoreleasing限定的變數會被隱式初始化為nil。
1、__strong
變數宣告預設都帶有__strong關鍵字,如果變數什麼關鍵字都不寫,那麼預設就是強參照。
2、__weak
上面已經看到了,這是弱參照的關鍵字。該概念是新特性,從 ios 5/ mac os x 10.7 開始匯入。由於該型別不影響物件的生命週期,所以如果物件之前就沒有持有者,那麼會出現剛建立就被破棄的問題,比如下面的**。
nsstring __weak *string = [[nsstring alloc] initwithformat:@"first name: %@", [self firstname]];
nslog(@"string: %@", string); //此時 string為空
如果編譯設定os版本 deployment target 設定為這比這低的版本,那麼編譯時將報錯(the current deployment target does not support automated __weak references),這個時候,我們可以使用下面的 __unsafe_unretained。
弱參照還有乙個特徵,即當引數物件失去所有者之後,變數會被自動付上nil (zeroing)。
3、__unsafe_unretained
該關鍵字與__weak一樣,也是弱參照,與__weak的區別只是是否執行nil賦值(zeroing)。但是這樣,需要注意變數所指的物件已經被破棄了,位址還還存在,但記憶體中物件已經沒有了。如果還是訪問該物件,將引起「bad_access」錯誤。
4、__autoreleasing
該關鍵字使對像延遲釋放。比如你想傳乙個未初始化的對像引用到乙個方法當中,在此方法中例項化此對像,那麼這種情況可以使用__autoreleasing。他被經常用於函式有值引數返回時的處理,比如下面的例子。
- (void) generateerrorinvariable:(__autoreleasing nserror **)paramerror
....
又如函式的返回值是在函式中申請的,那麼希望釋放是在呼叫端時,往往有下面的**。
-(nsstring *)stringtest
// 使用arc
-(nsstring *)stringtest
即當方法的引數是id*,且希望方法返回時物件被autoreleased,那麼使用該關鍵字。
總結:
今天,我們看到了基本的arc使用規則
內點法python 內點法
文字理解 內點法屬於約束優化演算法。約束優化演算法的基本思想是 通過引入效用函式的方法將約束優化問題轉換成無約束問題,再利用優化迭代過程不斷地更新效用函式,以使得演算法收斂。內點法 罰函式法的一種 的主要思想是 在可行域的邊界築起一道很高的 圍牆 當迭代點靠近邊界時,目標函式徒然增大,以示懲罰,阻止...
Hibernate框架的內連線和迫切內連線
public class hqltest catch exception e finally test public void fun2 內連線,以陣列方式進行儲存 string hql from customer c inner join c.setperson query query sessi...
AngularJS內的服務
通過之前講解的一些angularjs裡面的一些功能j 今天就來說下我用angulaerjs裡面的服務的一些感觸和運用。angularjs中你可以自己建立自己的服務,也可以使用angularjs裡面的內建服務。在angularjs中,服務是乙個函式或物件,可在你的angularjs 應用中使用。有個 ...