nonatomic, retain,weak,strong用法詳解
strong weak
strong與weak是由ARC新引入的物件變數屬性 ARC引入了新的物件的新生命週期限定,即零弱引用。如果零弱引用指向的物件被deallocated的話,零弱引用的物件會被自動設定為nil。@property(strong) MyClass *myObject; 相當於@property(retain) MyClass *myObject;
@property(weak) MyOtherClass *delegate; 相當於@property(assign) MyOtherClass *delegate;
強引用與弱引用的廣義區別:
強引用也就是我們通常所講的引用,其存亡直接決定了所指物件的存亡。如果不存在指向一個物件的引用,並且此物件不再顯示列表中,則此物件會被從記憶體中釋放。
弱引用除了不決定物件的存亡外,其他與強引用相同。即使一個物件被持有無數個若引用,只要沒有強引用指向他,那麼其還是會被清除。沒辦法,還是 “強哥” 有面子。
簡單講strong等同retain
weak比assign多了一個功能,當物件消失後自動把指標變成nil,好處不言而喻。
__weak, __strong 用來修飾變數,此外還有 __unsafe_unretained, __autoreleasing 都是用來修飾變數的。
__strong 是預設的關鍵詞。
__weak 聲明瞭一個可以自動 nil 化的弱引用。
__unsafe_unretained 宣告一個弱應用,但是不會自動nil化,也就是說,如果所指向的記憶體區域被釋放了,這個指標就是一個野指標了。
__autoreleasing 用來修飾一個函式的引數,這個引數會在函式返回的時候被自動釋放。
之前寫一個基於地理位置應用程式的時候無法讓應用程式開啟定位功能,在.h檔案裡面,我定義的屬性是這樣的:
後來,我將上面這句話改為:
@property(nonatomic, retain) CLLocationManager *locationManager;
就可以了。
接下來,就詳細得介紹一下nonatomic, retain,weak,strong
在我們開發iOS程式時,常常會遇到:
property 和synthesize,以前很懶沒有仔細去理解,只是看了看別人寫的書,覺得挺容易的(在這裡我不得不說,現在很多本土出的土書,尤其是早期的2009年,寫的是真亂,誤人子弟),所以今天有時間,自己試驗了一番,希望和大家討論。property,他可以提供的功能有:提供成員變數的訪問方法的宣告、控制成員變數的訪問許可權、控制多執行緒時成員變數的訪問環境 )。property不但可以在interface,在協議[url=]protocol[/url]
不過這裡還有有一點細微的差別,後面我會講到。
先講property大家都知道:@property(attribute1 , attribute2, ...])是@property的他的官方表達方式,所以看到attribute1, attribute2,你就應該懂的, 他的用法不是很簡單。下面就對他的屬性列表進行分類介紹:下面對屬性列表進行一下簡單的介紹,後續會用程式碼來解釋。1.可讀性:readonly 、readwrite@property(readwrite,....) valueType value;
其實他們都可以用程式碼表示:1.nonatomic 和 atomic@property(nonatomic ) NSObject* test1;
@synthesize test1;上面兩句程式碼,表示我們對test1的訪問,是非多執行緒安全的。@property(atomic) NSObject* test1;
@synthesize test1;上面兩句程式碼,表示我們對test1的訪問,是多執行緒安全的。其實也就是在講該成員變數放到互斥程式碼中,例如,下面進行加鎖。[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
就如上面所說 ,這兩個屬性,是出於對多執行緒條件下 ,對test1的訪問安全。如果你的程式的成員變數不存在安全問題,用nonatomic 就好,因為這樣不要在訪問是進行互斥,效率更高。2. readonly 、readwrite (注,後續過程我們都會加入nonatomic 屬性,因為它是十分普遍的)2.1 readonly@property(nonatomic ,readonly) NSObject* test1;
@synthesize test1;上面的兩句程式碼,objc編輯器將會為我們翻譯為:@property(nonatomic ,readonly) NSObject* test1; 等同-(NSObject*)test1;
@synthesize test1;等同-(NSObject*)test1{ return test1;}2.2 readwrite
@property(nonatomic ,readwrite ) NSObject* test1;
@synthesize test1;上面的兩句程式碼,objc編輯器將會為我們翻譯為:@property(nonatomic ,readwrite ) NSObject* test1; 等同-(NSObject*)test1;
-(void)settest1(NSObject* other);@synthesize test1;等同-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{ test1 = other;} 這裡要說明一下, readonly 、readwrite 這兩個屬性他們的真正價值,不是提供成員變數訪問介面,而是控制 成員變數的訪問許可權。所以要抓住他們真正價值。3. assign@property(nonatomic ,assign) NSObject* test1;@synthesize test1;上面兩句:objc編輯器將會翻譯如下:@property(nonatomic ,assign) NSObject* test1;等同 -(void)settest1(NSObject* other);@synthesize test1;-(void)settest1(NSObject* other);等同
{ test1 = other;}
4. retain@property(nonatomic ,retain) NSObject* test1;
@synthesize test1; objc編輯器翻譯如: @property(nonatomic ,retain) NSObject* test1;等同-(NSObject*)test1;
-(void)settest1(NSObject* other); @synthesize test1;
-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other) { if (test1!= other) { [test1release]; test1= [otherretain]; }}5. copy@property(nonatomic ,copy) NSObject* test1;
@synthesize test1; objc編輯器將翻譯如: @property(nonatomic ,copy) NSObject* test1;
-(NSObject*)test1;
-(void)settest1(NSObject* other); @synthesize test1;
-(NSObject*)test1{ return test1;}-(void)settest1(NSObject* other);
{ if (test1!=other) {
[test1release];
test1= [othercopy];
} }對於Copy屬性有一點要主要,被定義有copy屬性的物件必須要符合NSCopying協議,並且你還必須實現了-(id)copyWithZoneNSZone*)zone該方法。
程式碼才是王道:都是一些簡單程式碼用例//為了更具有普遍性,我選擇用自定義物件testObj /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .h
@interface testObj : NSObject<NSCopying>{
}
@end
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//testObj .m-(id)copyWithZoneNSZone *)zone
{
testObj* pObj = [[testObj allocWithZone:zone] init];
return pObj;
}
@end
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////testApp是包含多個testObj 物件指標//testApp .h
@interface testApp :
{
testObj* test1;
testObj* _test2;
}
@property(nonatomic , retain) NSObject* test1;
@property(nonatomic , copy) NSObject* test2;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//[email protected] test1;@synthesize test2 = _test2;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@synthesize test2 = _test2; //對這裡要特別主要一下,這裡可以看作是一種別名機制,這點和前面類比的C++標頭檔案和Cpp檔案不同。
例如對於setter函式,objc編輯器將會按如下方式翻譯如果是@synthesize _test2;setter函式將是這種形式:-(void)set_test2(NSObject*); //注意中間的下劃線寫成@synthesize test = _test2;setter函式將是這種形式:
-(void)settest2(NSObject*);// _test2 被 test2替換了
可以看出這種別名機制,感覺是規範書寫(其實更像是規範Objc的書寫,大家可以看看官方文件中,成員變數都是前面帶下滑線的(如_test2),所以才搞了這樣一個別名規範程式碼中的書寫)
//下面是一個功能函式,-(void )test{test1 = [[testObj alloc]init];// test1 retainCount =1;
//下面有三種對test2操作方法: _test2 = test1; //這裡是將test1的指標賦值給_test2指標,注意,並沒有呼叫test2的setter方法 ,所以test retainCount = 1、 test2 retainCount = 0; self.test2 = test1; //這裡呼叫test2的Copy方法,因此這是test retainCount = 1、 test2 retainCount = 1; test2 = test1; //這段程式碼系統將會提示出錯說test2沒有定義。因為這裡編譯器認為是一條賦值表示式,將test2看作是一個成員變數,而在我們的testApp 中是沒有這個成員變數的,這裡要區別我們所說的別名,別名機制可以看作是在呼叫setter或者getter函式才會起作用,而這裡只是一個簡單的賦值,也就出現未定義的錯誤。如果沒有理解,你就記住要呼叫setter或者getter函式,就用"self.成員變數"這種形式就行了.
//我們把 test2 = test1這行程式碼註釋掉,保證程式繼續執行 [test1 release]; // 釋放test1 ,test1 retainCount = 0;
[test2 release]; // 釋放test2 ,test2 retainCount = 0;
}@end
相關推薦
nonatomic, retain,weak,strong用法詳解
strong weak strong與weak是由ARC新引入的物件變數屬性 ARC引入了新的物件的新生命週期限定,即零弱引用。如果零弱引用指向的物件被deallocated的話,零弱引用的物件會被自動設定為nil。 @property(strong) MyClass *
object-c學習:@property 屬性中 assign,nonatomic,retain,strong,weak的區別
strong關鍵字與retain關似,用了它,引用計數自動+1,用例項更能說明一切 @property (nonatomic, strong) NSString *string1; @property (nonatomic, strong) NSString *string2; 有這樣兩個屬性
JavaScript中return的用法詳解
style 返回 www log tle blog 意思 charset fun 1、定義:return 從字面上的看就是返回,官方定義return語句將終止當前函數並返回當前函數的值,可以看下下面的示例代碼: <!DOCTYPE html><html l
SVN trunk(主線) branch(分支) tag(標記) 用法詳解和詳細操作步驟
trac load mar span 必須 最可 objc copy 右鍵 原文地址:http://blog.csdn.net/vbirdbest/article/details/51122637 使用場景: 假如你的項目(這裏指的是手機客戶端項目)的某個版本(例如1.0
js 定時器用法詳解——setTimeout()、setInterval()、clearTimeout()、clearInterval()
ntb 幫助 .get tint num 用法 -c 函數 tel 在js應用中,定時器的作用就是可以設定當到達一個時間來執行一個函數,或者每隔幾秒重復執行某段函數。這裏面涉及到了三個函數方法:setInterval()、setTimeout()、clearI
selenium用法詳解
key url enc element api code 需要 int question selenium用法詳解 selenium主要是用來做自動化測試,支持多種瀏覽器,爬蟲中主要用來解決JavaScript渲染問題。 模擬瀏覽器進行網頁加載,當requests,url
C# ListView用法詳解
ont 結束 server 發生 匹配 鼠標 之前 小圖標 order 一、ListView類 1、常用的基本屬性: (1)FullRowSelect:設置是否行選擇模式。(默認為false) 提示:只有在Details視圖該屬性才有意義
linux cp命令參數及用法詳解---linux 復制文件命令cp
linux file linux cp命令參數及用法詳解---linux 復制文件命令cp [root@Linux ~]# cp [-adfilprsu] 來源檔(source) 目的檔(destination)[root@linux
Python數據類型方法簡介一————字符串的用法詳解
python 字符串連接 字符串用法 符串是Python中的重要的數據類型之一,並且字符串是不可修改的。 字符串就是引號(單、雙和三引號)之間的字符集合。(字符串必須在引號之內,引號必須成對)註:單、雙和三引號在使用上並無太大的區別; 引號之間可以采取交叉使用的方式避免過多轉義;
C# ListView用法詳解(轉)
分組 創建 cti 排列 checkbox 定義 com 程序 erl 一、ListView類 1、常用的基本屬性: (1)FullRowSelect:設置是否行選擇模式。(默認為false) 提示:只有在Details視圖該屬性才有
java中的instanceof用法詳解
定義 xtend print 繼承 interface 參數 保留 如果 ack instanceof是Java的一個二元操作符(運算符),也是Java的保留關鍵字。它的作用是判斷其左邊對象是否為其右邊類的實例,返回的是boolean類型的數據。用它來判斷某個對象是否是
@RequestMapping 用法詳解
同時 get() turn example track find 說明 tex -h 簡介: @RequestMapping RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
Css中路徑data:image/png;base64的用法詳解 (轉載)
javascrip base64編碼 asc cda 文件的 color 情況 ont 背景圖片 大家可能註意到了,網頁上有些圖片的src或css背景圖片的url後面跟了一大串字符,比如: background-image:url(data:image/png;bas
global用法詳解
global 在函數內傳遞參數1、global一般用在函數內,將外部變量參數傳遞至函數內部,用法為:<?php $name = "why"; function changeName(){ global $name; $name = "what";
java中靜態代碼塊的用法—— static用法詳解
super關鍵字 了解 裝載 static關鍵字 super 屬於 註意 lock 自動 (一)java 靜態代碼塊 靜態方法區別一般情況下,如果有些代碼必須在項目啟動的時候就執行的時候,需要使用靜態代碼塊,這種代碼是主動執行的;需要在項目啟動的時候就初始化,在不創建對象的
<!CDATA[]]用法詳解
引號 ica lap 用法 bsp mar ret message eight 所有 XML 文檔中的文本均會被解析器解析。 只有 CDATA 區段(CDATA section)中的文本會被解析器忽略。 PCDATA PCDATA 指的是被解析的字符數據(Parsed
Es6 Promise 用法詳解
set 問題 得到 math clas promise 回調 console spa Promise是什麽?? 打印出來看看 console.dir(Promise) 這麽一看就明白了,Promise是一個構造函數,自己身上有all、reject、r
[轉] angular2-highcharts用法詳解
ppc tip option select sel nbsp 用法詳解 points ttr 1、 使用npm安裝angular2-highcharts npm install angular2-highcharts --save 2、主模塊中引入 app.module.t
常見<meta>的基本用法詳解
代碼 簡介 clas 元素 word spa wid min mpat <meta charset="utf-8"> 定義與name 屬性相關的信息,使用 utf-8編碼方式編譯字符 <meta http-equiv="X-UA-Compatible" c
oracle中的exists 和not exists 用法詳解
sdn ref 用法詳解 html nbsp e30 .net tail sin oracle中的exists 和not exists 用法詳解 http://blog.csdn.net/zhiweianran/article/details/7868894oracle