1、假設你用malloc分配了一塊內存,並且把它的地址賦值給了指針1,後來你希望指針b,也可以共享這塊內存,於是你又把a賦值給了b(assign)。此時a和b指向同一塊內存,請問,當a不再需要這塊內存,能否直接釋放它?答案是否定的,因爲a並不知道b是否還在使用這塊內存,如果a釋放了,那麼b在使用這塊內存的時候會引起程序crash掉(message sent to deallocated instance內存問題)。
2、瞭解到1中的assign問題,那麼如何解決?最簡單的一個方法就是使用引用計數(reference counting),還是上面的例子,我們給那塊內存設定一個引用計數,當內存被分配並且賦值給a時,引用計數是1.當把a賦值給b時引用計數增加到2.這是如果a不再使用這塊內存,它只需要把引用計數減1,表明自己不再擁有這塊內存。b不再使用時也把引用計數減1.當引用計數爲0的時候,代表該內存不再被人戶指針所引用,系統可以把它直接釋放掉。
3、上面兩點其實就是assign和retain的區別,assgn就是直接賦只,從而可能引起1中的問題,當數據爲int,float等c的原聲類型時,可以使用assign。retain就如2中那樣使用了引用計數,retain引起引用計數加1,release引起引用計數減1,當引用計數爲0時,dealloc函數回收內存。(Xcode4.2之後,arc的出現減少了程序員們手動釋放的工作,retain,和release,在自動釋放池中就可不必添加,但是arc早起的類庫,例如ASIHTTP,Reachability,ASINetWork等,在添加時就要注意了,在工程的Build Phases中加入-fno-objc-arc,即可)。
4、copy是在你不希望a和b共享一塊內存時會用到。a和b各自又自己的內存。(複製內容,而不是複製指針)
1、assign:用於非指針變量。用於基礎數據類型(例如NSInteger)和c數據類型(int,float,double,char)另外還有id,反正記住:前面不加"*(星)"的就用assign吧
2、retian:釋放舊的對象,將舊對象的只賦予輸入對象,再提高輸入對象的索引計數爲1,用於指針變量。就是說你定義了一個變量,然後這個變量再程序的運行中會被更改,並影響到其他方法(例如,跨類穿參,參數的賦值)。xcode4.3以後,retian和strong基本一樣
3、copy:效果和retain差不多,唯一的區別就是copy只能用於NSString,如果一個類繼承NSObject,那麼這個類裏面的屬性需要使用copy。
4、retain是指針拷貝,copy是內容拷貝。
篇後話:
雖然是一篇很簡單的文章,但是很多新手,包括老手,在使用的時候還是會遇到問題,例如weak的弱引用(block中使用)的具體實現原理,從oc一直分析下去,一直分析到計算幾的工作原理,如果不會,還是虛心的查一下,或是問一下,編程這個東西不能只看結果,在原理不清的情況下,即使實現了功能,你的項目會有很多隱藏的bug(非常危險),這就是一個優秀程序員和**程序員的區別,後續會介紹一下,coredata的使用,sqlite的具體使用,ASIHTTP的使用,block的使用,程序的異常拋出機制@try,百度運推送的,蘋果apns推送,base64加密方法,xmpp的簡單使用,gcd,php接口的簡單書寫,等等。自己在自學Java,c++中,希望可以和愛好相同的朋友一起探討。向大神們學習。