readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak屬性的作用分別是什么。
關(guān)鍵字注釋
readwrite此標(biāo)記說明屬性會被當(dāng)成讀寫的榜掌,這也是默認(rèn)屬性只厘。
readonly此標(biāo)記說明屬性只可以讀,也就是不能設(shè)置祭埂,可以獲取面氓。
assign不會使引用計數(shù)加1,也就是直接賦值沟堡。
retain會使引用計數(shù)加1侧但。
copy建立一個索引計數(shù)為1的對象,在賦值時使用傳入值的一份拷貝航罗。
nonatomic非原子性訪問禀横,多線程并發(fā)訪問會提高性能。
atomic原子性訪問粥血。
strong打開ARC時才會使用柏锄,相當(dāng)于retain。
weak打開ARC時才會使用复亏,相當(dāng)于assign趾娃,可以把對應(yīng)的指針變量置為nil。
為什么代理要用weak缔御?
首先明白什么情況使用 weak 關(guān)鍵字?
在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用 weak 來解決
delegate 代理屬性,代理屬性也可使用
assign自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次,此時也會使用 weak
自定義IBOutlet 控件屬性一般也使用weak;當(dāng)然,也可以使用 strong,但是建議使用 weak
weak 在屬性所指的對象遭到摧毀時,系統(tǒng)會將 weak 修飾的屬性對象的指針指向 nil,在 OC 給 nil 發(fā)消息是不會有什么問題的;如果使用 assign 策略在屬性所指的對象遭到摧毀時,屬性對象指針還指向原來的對象,由于對象已經(jīng)被銷毀,這時候就產(chǎn)生了野指針,如果這時候在給此對象發(fā)送消息,很容造成程序奔潰assigin 可以用于修飾非 OC 對象,而 weak 必須用于 OC 對象抬闷。
block和代理的區(qū)別?
block 和 delegate 都可以通知外面。block 更輕型耕突,使用更簡單笤成,能夠直接訪問上下文,這樣類中不需要存儲臨時數(shù)據(jù)眷茁,使用 block 的代碼通常會在同一個地方炕泳,這樣讀代碼也連貫。delegate 更重一些上祈,需要實現(xiàn)接口培遵,它的方法分離開來,很多時候需要存儲一些臨時數(shù)據(jù)登刺,另外相關(guān)的代碼會被分離到各處籽腕,沒有 block 好讀。
應(yīng)該優(yōu)先使用 block塘砸。而有兩個情況可以考慮 delegate节仿。
1. 有多個相關(guān)方法。假如每個方法都設(shè)置一個 block, 這樣會更麻煩掉蔬。而 delegate 讓多個方法分成一組廊宪,只需要設(shè)置一次矾瘾,就可以多次回調(diào)瞻鹏。當(dāng)多于 3 個方法時就應(yīng)該優(yōu)先采用 delegate烤黍。
2. 為了避免循環(huán)引用嫁审,也可以使用 delegate磅废。使用 block 時稍微不注意就形成循環(huán)引用兽埃,導(dǎo)致對象釋放不了侦鹏。這種循環(huán)引用铜跑,一旦出現(xiàn)就比較難檢查出來湿右。而 delegate 的方法是分離開的荐操,并不會引用上下文芜抒,因此會更安全些。
將 block 簡單分類托启,有三種情形宅倒。
* 臨時性的,只用在棧當(dāng)中屯耸,不會存儲起來拐迁。比如數(shù)組的 foreach 遍歷,這個遍歷用到的 block 是臨時的疗绣,不會存儲起來线召。
* 需要存儲起來,但只會調(diào)用一次多矮,或者有一個完成時期缓淹。比如一個 UIView 的動畫,動畫完成之后塔逃,需要使用 block 通知外面割卖,一旦調(diào)用 block 之后,這個 block 就可以刪掉患雏。
* 需要存儲起來,可能會調(diào)用多次罢维。比如按鈕的點擊事件淹仑,假如采用 block 實現(xiàn),這種 block 就需要長期存儲肺孵,并且會調(diào)用多次匀借。調(diào)用之后,block 也不可以刪除平窘,可能還有下一次按鈕的點擊吓肋。
對于臨時性的,只在棧中使用的 block, 沒有循環(huán)引用問題瑰艘,block 會自動釋放是鬼。而只調(diào)用一次的 block肤舞,需要看內(nèi)部的實現(xiàn),正確的實現(xiàn)應(yīng)該是 block 調(diào)用之后均蜜,馬上賦值為空李剖,這樣 block 也會釋放,同樣不會循環(huán)引用囤耳。而多次調(diào)用時篙顺,block 需要長期存儲,就很容易出現(xiàn)循環(huán)引用問題充择。
Cocoa 中的 API 設(shè)計也是這樣的德玫,臨時性的,只會調(diào)用一次的椎麦,采用 block宰僧。而多次調(diào)用的,并不會使用 block铃剔。比如按鈕事件撒桨,就使用 target-action,有些庫將按鈕事件從 target-action 封裝成 block 接口, 反而容易出問題键兜。