這有幾個層次。
首先,聲明的屬性大多隻是聲明存取方法的捷徑。如果不提供自己的實現,則默認情況下發生的編譯器綜合屬性會定義這些方法和實例變量以支持該屬性。
所以,這樣的:
@property(atomic,assign) NSInteger sum;
基本上只是這樣的:
- (NSInteger) sum;
- (void) setSum:(NSInteger)value;
屬性的合成產生的那些方法的一個實例變量和實施方式:
@implementation ...
{
NSUInteger _sum;
}
- (NSInteger) sum
{
// ...
}
- (void) setSum:(NSInteger)value
{
// ...
}
對於原子性質,實現-sum
和-setSum:
各自保證運行,以至於兩者都不會中斷另一方。與-setSum:
調用「同時」發生的-sum
的調用將返回-setSum:
之前的值或之後的值,但不會返回部分修改的frankenstein值或任何臨時值。同樣,同時撥打-setSum:
的兩個電話將導致_sum
具有來自其中一個或另一個電話的值,但從不會有一些混合或臨時值。這兩個電話似乎是以嚴格的順序發生的,無論是A然後B還是B然後A是任意的。
這對於具有複合類型的房產比較容易理解,如NSRect
。設置該屬性的兩個線程永遠不會導致例如來自一個線程的origin
和來自另一個線程的size
被存儲。一方或另一方將「贏」,並且協議將保持一致。同樣,調用getter的線程也不會看到混合值,即使它與調用者的調用同時發生。
接下來,使用點語法訪問屬性(例如self.sum
)實際上只是調用訪問器的快捷方式。因爲只有get和set訪問,並沒有任何「增值」訪問,就像self.sum++;
需求的語句來完成這兩個,分別:
[self setSum:[self sum] + 1];
所以,你的語句首先涉及到一個呼叫-sum
然後到-setSum:
通話每個線程。沒有什麼能夠確保其他線程不能彼此交錯操作。該屬性的原子性並不妨礙它。也就是說,線程A可以從它的調用-sum
得到值5,線程B也可以從它的調用-sum
得到值5,每一個都可以計算6作爲新值,然後他們都稱-setSum:
與值6。所以,兩個線程都「增加」的屬性,但它只會增加了1
總之,原子是不是線程安全的。認爲它是一個概念錯誤。這只是原子性。它確實可以防止多線程同時訪問同一個屬性時可能發生的一種腐敗,但不是所有類型的。
你得到什麼結果呢? – rmaddy
爲什麼你在循環內而不是在循環之前創建隊列? – rmaddy
997 998 996不1000,在循環,使1000個線程循環之前 – NickYu