2010-02-12 88 views

回答

257

MrMage鏈接的文章不再有效。所以,下面是我在Objective-C中短時間內學到的知識:

非原子對原子 - 「atomic」是默認值。始終使用「非原子」。我不知道爲什麼,但是我讀過的書中說,使用「原子」「很少有理由」。 (順便說一下:我讀的書是BNR的「iOS編程」一書。)

readwrite與只讀 - 「readwrite」是默認值。當你@synthesize時,你會爲你創建一個getter和一個setter。如果您使用「只讀」,則不會創建setter。在實例化對象後,將它用作您不想更改的值。

保留與副本與分配

  • 「分配」 是默認的。在由@synthesize創建的setter中,該值將被簡單地分配給該屬性。我的理解是,「分配」應該用於非指針屬性。
  • 當屬性是指向對象的指針時,需要「保留」。 @synthesize生成的setter將保留(也就是添加一個保留計數)該對象。完成後您需要釋放對象。
  • 當對象可變時需要「複製」。如果此時需要此對象的值,請使用此選項,並且您不希望該值反映該對象的其他所有者所做的任何更改。由於您保留了副本,因此在完成對象時需要釋放該對象。
+0

@Blamdarot - 我需要與ARC釋放以及 – Dejell 2012-12-27 15:48:15

+9

@Odelya - 不,如果你在使用ARC時釋放,我相信你會得到一個編譯器錯誤。 – Blamdarot 2012-12-28 19:22:53

+41

「總是使用非原子」是不好的建議。你應該知道當你使用非原子時你放棄了什麼。 – 2013-10-24 01:42:24

7

原子屬性一次只能由一個線程訪問。它是線程安全。默認值是原子的。請注意,在沒有關鍵字原子

非原子意味着多個線程可以訪問該項目。它是線程不安全

所以在使用原子一個應該非常小心。因爲它會影響您的代碼

+2

「注意:屬性原子性與對象的線程安全性不是同義的。」從https://developer.apple。com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#// apple_ref/doc/uid/TP40011210-CH5-SW4 – jk7 2015-12-16 01:40:31

132

的性能閱讀多篇文章後,我決定一起把所有的屬性信息:

  1. 原子//默認
  2. 非原子
  3. 強=保留// default
  4. weak = unsafe_unretained
  5. retain
  6. 分配//默認
  7. unsafe_unretained
  8. 副本
  9. 只讀
  10. 讀寫//默認

下面是詳細的文章,你可以找到這些屬性的鏈接。

非常感謝所有在這裏給出最佳答案的人!

Variable property attributes or Modifiers in iOS

這裏是從第樣本描述

  1. 原子 - 原子是指只有一個線程訪問的變量(靜態類型)。 -Atomic是線程安全的。 - 但性能較差 -atomic是默認行爲 - 非垃圾收集環境中的原子訪問器(即使用保留/釋放/自動釋放時)將使用鎖來確保另一個線程不會干擾正確設置/獲取值。 - 它實際上不是關鍵字。

實施例:

@property (retain) NSString *name; 

@synthesize name; 
  • 非原子 -Nonatomic意味着多線程訪問的變量(動態型)。 - 單體是線程不安全的。 - 但它在性能上很快 - 不是默認行爲,我們需要在屬性屬性中添加非原子關鍵字。 - 當兩個不同的進程(線程)同時訪問同一個變量時,可能會導致意外行爲。
  • 例子:

    @property (nonatomic, retain) NSString *name; 
    
    @synthesize name; 
    

    解釋:

    假設有一個名爲 「名」 原子串屬性,如果你調用[自我的setName:@ 「A」]從線程A, 從線程B調用[self setName:@「B」],並從線程C調用[self name],然後所有在不同線程上的操作都將被串行執行,這意味着如果一個線程正在執行setter或getter,則其他線程將等待。這使屬性「名稱」可讀/寫安全,但如果另一個線程D同時調用[名稱釋放],則此操作可能會導致崩潰,因爲此處不涉及setter/getter調用。這意味着一個對象是可讀/寫安全的(ATOMIC),但不是線程安全的,因爲另一個線程可以同時向對象發送任何類型的消息。開發人員應確保此類對象的線程安全。

    如果屬性「name」是非原子的,則上面示例中的所有線程--A,B,C和D將同時執行,從而產生任何不可預知的結果。在原子情況下,A,B或C中的任何一個將首先執行,但D仍可以並行執行。

  • (iOS4的保留=) - 它表示「記住這堆直到我不指向它了」 - 換句話說「我'所有者,您不能在與保留相同的目標前重新分配「 - 只有在需要保留該對象時才能使用強壯。 - 默認情況下,所有實例變量和局部變量都是強指針。 -我們通常對UIViewControllers(UI項目的父母)使用較強 -strong與ARC一起使用,它基本上可以幫助您,無需擔心對象的保留數。 ARC完成後會自動爲您發佈。使用關鍵字strong意味着您擁有該對象。
  • 實施例:

    @property (strong, nonatomic) ViewController *viewController; 
    
    @synthesize viewController; 
    
  • (iOS4的= unsafe_unretained) - 它表示 「只要別人點強烈保留此將其」 - 與分配,保留或發佈一樣 - 「弱」引用是您不保留的引用。 -我們通常對IBOutlets(UIViewController的Childs)使用weak。這是可行的,因爲只要父對象具有子對象 就需要存在。 弱引用是一個引用,它不保護引用的對象不被垃圾收集器收集。 -弱者本質上是一種不再保留的財產。除了當對象被釋放弱指針會自動設置爲無
  • 例子:

    @property (weak, nonatomic) IBOutlet UIButton *myButton; 
    
    @synthesize myButton; 
    

    強&弱說明,Thanks to BJ Homer

    想象我們的對象是狗,並且狗想逃跑(被釋放)。 強壯的指針就像狗上的皮帶。只要你有狗附着的皮帶,狗就不會逃跑。如果五個人把一條狗綁在一條狗上,(五個指向一個物體的強指針),那麼只有當所有五條皮帶分開時,狗才不會跑掉。 另一方面,弱指針就像小孩子指着狗說,「看!一隻狗!」只要狗還在皮帶上,小孩們仍然可以看到狗,他們仍然會指向它。不過,只要所有的皮帶都脫落,無論有多少小孩指着它,狗都會跑掉。 只要最後一個強指針(皮帶)不再指向一個對象,該對象就會被釋放,所有弱指針將被清零。 當我們使用弱? 唯一一次你想使用弱,是如果你想避免保留週期 (例如,父母保留孩子,孩子保留父母,所以永遠不會被釋放)。

  • 保留 =強 -it被保留,舊值被釋放,它被分配 -retain指定新值應該在分配和舊值被髮送-retain發送-release -retain是一樣強。蘋果說,如果你寫保留它會自動轉換/工作只有強壯。 - 方法如 「黃金」 包括隱含的 「保留」
  • 實施例:

    @property (nonatomic, retain) NSString *name; 
    
    @synthesize name; 
    
  • 分配 -assign是默認設置,簡單地進行變量賦值 -assign是一個屬性屬性,告訴編譯器如何綜合屬性的setter實現 -I將使用C語言屬性的賦值,而弱賦值給Objective-C對象。
  • 實施例:

    @property (nonatomic, assign) NSString *address; 
    
    @synthesize address; 
    
  • unsafe_unretained

    -unsafe_unretained是所有權限定符,告訴ARC如何插入保留/釋放調用 - unsafe_unretained是分配的ARC版本。

  • 實施例:

    @property (nonatomic, unsafe_unretained) NSString *nickName; 
    
    @synthesize nickName; 
    
  • 拷貝當對象是可變 -copy是必需的。 -copy指定應發送的新值-copy賦值和舊值發送-release。 -copy就像保留返回一個對象,你必須在非垃圾收集環境中明確釋放(例如,在dealloc中)。 如果您使用副本,那麼您仍然需要在dealloc中釋放該副本。 - 如果此時需要此對象的值,請使用此選項,並且您不希望該值反映該對象的其他 所有者所做的任何更改。由於您保留了副本,因此在完成對象時需要釋放該對象。
  • 例子:

    @property (nonatomic, copy) NSArray *myArray; 
    
    @synthesize myArray; 
    
    +2

    我認爲,在弧之後,不再使用保留。 – mert 2014-12-08 10:03:37

    +1

    完整列表未命中2個選項:setter和getter,這也是唯一需要參數的選項。 – 2015-08-06 05:24:34

    265

    你知道@屬性的屬性之前,您應該知道什麼是使用@屬性的。

    • @property提供了一個方法來定義一個類被用於封裝的信息。 如果您使用@property聲明對象/變量,那麼該對象/變量將可被導入其類的其他類訪問。

    • 如果聲明在頭文件使用@property一個對象,那麼你必須在實現文件中使用@synthesize合成它。這使得對象KVC兼容。默認情況下,編譯器將爲該對象合成訪問器方法

    • 存取方法是:setter和getter。

    例子: .H

    @interface XYZClass : NSObject 
    @property (nonatomic, retain) NSString *name; 
    @end 
    

    .M

    @implementation XYZClass 
    @synthesize name; 
    @end 
    

    現在,編譯器將綜合存取方法

    XYZClass *obj=[[XYZClass alloc]init]; 
    NSString *name1=[obj name]; // get 'name' 
    [obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method 
    
    • @property

      原子,非原子,保留,複製,只讀,讀寫,分配,強,吸氣劑=方法,設置器方法=屬性列表,unsafe_unretained

    • 原子是默認行爲。如果一個對象被聲明爲原子,那麼它就變成了線程安全的。線程安全的手段,一次只有該類的特定實例的一個線程可以控制該對象。

    如果線程正在執行getter方法,則其他線程無法對該對象執行setter方法。它很慢。

    @property NSString *name; //by default atomic` 
    @property (atomic)NSString *name; // explicitly declared atomic` 
    
    • 非原子不是線程安全的。您可以使用nonatomic屬性來指定合成訪問器直接設置或返回值,但不保證如果從不同線程同時訪問相同的值會發生什麼情況。

    由於這個原因,訪問非原子性質比原子性質快。

    @property (nonatomic)NSString *name; 
    
    • 保留當屬性是一個指向對象是必需的。

    該setter方法將增加該對象的保留計數,以便它將佔用自動釋放池中的內存。

    @property (retain)NSString *name; 
    
    • 副本如果使用複製,則不能使用保留。使用該類的副本實例將包含其自己的副本。

    即使設置了可變字符串並隨後更改,實例也會捕獲它在設置時的值。將不會合成setter和getter方法。

    @property (copy) NSString *name; 
    

    現在,

    NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];  
    xyzObj.name = nameString;  
    [nameString appendString:@"Pizza"]; 
    

    將不受影響。

    • 只讀如果您不希望允許通過setter方法要更改的屬性,可以只讀申報財產。

    編譯器將生成一個getter,但不會生成setter。

    @property (readonly) NSString *name; 
    
    • 讀寫是默認行爲。您不需要明確指定readwrite屬性。

    它只是只讀的對面。

    @property (readwrite) NSString *name; 
    
    • 分配將產生的值的實例變量直接分配,而不是複製或保持它的裝定。這對於像NSInteger和CGFloat這樣的原始類型或者不直接擁有的對象(例如委託)來說是最好的。

    請記住,啓用垃圾回收時保留和賦值基本上是可以互換的。

    @property (assign) NSInteger year; 
    
    • 是保留的替代品。

    它帶有ARC。

    @property (nonatomic, strong) AVPlayer *player; 
    
    • 的getter方法=如果要使用不同的名稱爲getter方法,它可以通過添加屬性的屬性來指定自定義名稱。

    在布爾屬性(屬性具有一個YES或NO的值)的情況下,它是常用於吸氣劑的方法,以與所述字起始「是」

    @property (getter=isFinished) BOOL finished; 
    
    • 的setter =方法如果要爲setter方法使用不同的名稱,可以通過向屬性添加屬性來指定自定義名稱。

    該方法應該以冒號結尾。

    @property(setter = boolBool:) BOOL finished; 
    
    • unsafe_unretained有可可和可可觸摸幾類,還不支持弱引用,這意味着你不能聲明弱屬性或弱的局部變量來跟蹤它們, 。這些類包括NSTextView,NSFont和NSColorSpace等。如果您需要對這些類中的某個類使用弱引用,則必須使用不安全的引用。

    不安全參考類似於它不保持其相關對象活着弱引用,但是如果目標對象被釋放它不會被設置爲

    @property (unsafe_unretained) NSObject *unsafeProperty; 
    

    如果需要指定多個屬性,只需把它們作爲一個逗號分隔的列表,像這樣:

    @property (readonly, getter=isFinished) BOOL finished; 
    
    +0

    此外,弱意味着沒有對該對象引用的引用計數,但它完全被引用或根本沒有引用。有點像「是的,引用了我的東西」與「對我的引用存在」(這就是強烈的東西)。 – 2013-08-16 19:35:15

    +5

    忽略關於垃圾收集的答案中的一行,因爲垃圾收集在Mac OS X中已棄用,並且每個[Apple文檔]的iOS中都不存在(https://developer.apple.com/library/mac/releasenotes/ObjectiveC/ RN-TransitioningToARC /介紹/ Introduction.html#// apple_ref/DOC/UID/TP40011226-CH1-SW17)。 – 2013-10-24 01:41:43

    +0

    每次我讀了一些關於obj-c屬性指令的信息時,我都很困惑!我需要知道它背後的計算機科學。任何人都可以將我鏈接到適當的文獻嗎? – AceN 2015-05-26 12:04:21

    相關問題