@property中屬性關(guān)鍵字

前言:

@property關(guān)鍵字對(duì)每一個(gè)iOS開(kāi)發(fā)者而言都不是陌生的勇哗,或許很多同行會(huì)說(shuō)哥們現(xiàn)在都swift了你再談這個(gè)還有毛用呢亲桥,話說(shuō)的不錯(cuò)抄罕,swift已經(jīng)越來(lái)越普及(據(jù)說(shuō)Swift語(yǔ)言殺入TIOBE 3月編程語(yǔ)言排行榜Top 10)秃流,更多的開(kāi)發(fā)者和公司已經(jīng)嘗試用OC和Swift混編的模式進(jìn)行開(kāi)發(fā)祸挪,有放的開(kāi)的已經(jīng)Swift無(wú)限玩耍起來(lái)。但是歸根結(jié)底OC是每個(gè)iOS開(kāi)發(fā)者的起點(diǎn),無(wú)論是出于基本功的要求,還是針對(duì)面試要求我們都有必要去了解更多澜躺,當(dāng)然這里只是隨便聊點(diǎn)一些平時(shí)需要注意到的,而非全部描述抒蚜。

@property 的本質(zhì)

答案:成員變量(ivar) + setter方法 + getter方法
“屬性” (property)作為 OC 的一項(xiàng)特性掘鄙,主要的作用就在于封裝對(duì)象中的數(shù)據(jù)。 OC 對(duì)象通常會(huì)把其所需要的數(shù)據(jù)保存為各種實(shí)例變量嗡髓,然后通過(guò)“存取方法”(access method)來(lái)訪問(wèn)操漠。“設(shè)置方法” (setter)用于寫入變量值器贩,“獲取方法” (getter)用于讀取變量值颅夺,但是存取方法有著嚴(yán)格的命名規(guī)范朋截。

@property(nonatomic, strong) NSMutableString *name;

上面一行代碼是定義一個(gè)name屬性,系統(tǒng)會(huì)自動(dòng)幫我們生成成員變量(ivar) 吧黄、 setter方法 部服、getter方法,有一種說(shuō)法叫“自動(dòng)合成”拗慨。

開(kāi)發(fā)中有時(shí)我們需要重寫屬性的setter/getter方法廓八,這里提下簡(jiǎn)單注意:

  • 如果同時(shí)重寫setter/getter方法,系統(tǒng)在不在自動(dòng)生成成員變量赵抢,需要手動(dòng)添加
  • 重寫copy類型的setter方法時(shí)記得在賦值時(shí)用copy剧蹂,否則外面的copy就是擺設(shè)
@interface ViewController ()

@property(nonatomic, copy) NSString *age;

@end

@implementation ViewController

- (void)setAge:(NSString *)age {
    // 賦值時(shí)用copy,否則外面的copy就是擺設(shè)
    _age = age.copy;
}

@end

nonatomic 和 atomic(原子性和非原子性)

atomic(原子性):默認(rèn)屬性烦却,編輯器合成的getter和setter方法通過(guò)鎖定機(jī)制保證屬性原子性宠叼,多線程環(huán)境下防止資源搶奪。但是由于鎖定機(jī)制的保護(hù)其爵,開(kāi)銷比較大冒冬, 這會(huì)帶來(lái)性能問(wèn)題。

{lock}
  if (property != newValue) {
    [property release];
    property = [newValue retain];
  }
{unlock}

nonatomic(非原子性):不使用自旋鎖摩渺,效率提高简烤,一般移動(dòng)端開(kāi)發(fā)都會(huì)聲明為nonatomic,多線程情下為保護(hù)資源安全則會(huì)用深層的鎖定機(jī)制才行(GCD/NSOperation)摇幻。

總結(jié):在iOS開(kāi)發(fā)中横侦,你會(huì)發(fā)現(xiàn),幾乎所有屬性都聲明為 nonatomic绰姻。但是在開(kāi)發(fā) Mac OS 程序時(shí)建議使用 atomic 枉侧,因?yàn)閕OS使用nonatomic存在性能問(wèn)題而Mac OS則不存在(心臟大不擔(dān)心干活問(wèn)題v)。

copy龙宏、mutableCopy

說(shuō)到copy首先要談到“淺拷貝”和“深拷貝”:

淺拷貝:指針拷貝棵逊,不同指針向同一塊內(nèi)存伤疙,操作的是同一個(gè)對(duì)象
深拷貝:對(duì)象拷貝银酗,開(kāi)辟出一塊新的內(nèi)存空間來(lái)存儲(chǔ)拷貝的對(duì)象,和原對(duì)象再無(wú)關(guān)聯(lián)(除了剛拷貝出爐時(shí)長(zhǎng)的像而已)

  • copy不可變對(duì)象(NSString, NSDictionary, NSArray等)徒像,淺拷貝黍特,得到不可變對(duì)象。
  • copy可變對(duì)象(NSMutableString, NSMutableDictionary, NSMutableArray等)锯蛀,深拷貝灭衷,得到不可變對(duì)象。
  • mutableCopy不可變對(duì)象(NSString, NSDictionary, NSArray等)旁涤,深拷貝翔曲,得到可變對(duì)象迫像。
  • mutableCopy可變對(duì)象(NSMutableString, NSMutableDictionary, NSMutableArray等),深拷貝瞳遍,得到可變對(duì)象闻妓。

注意:copy出來(lái)得到的對(duì)象都是不可變的,而MutableCopy出來(lái)得到的對(duì)象都是可變的掠械。

問(wèn)題:字符串為什么用copy?
這里有個(gè)簡(jiǎn)單的小例子由缆,一個(gè)對(duì)象擁有一個(gè)可變字符串屬性,我們strong修飾而不用copy

#import "ViewController.h"

@interface ViewController ()

@property(nonatomic, strong) NSMutableString *name;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    NSMutableString *strM = [NSMutableString stringWithString:@"jerry"];
    self.name = strM;
    
    NSLog(@"self.name = %@", self.name);
    [strM appendString:@" say hello"];
    NSLog(@"self.name = %@", self.name);
}

@end

控制臺(tái)輸入結(jié)果為:
2017-03-15 10:00:01.272 01[3109:32607] self.name = jerry
2017-03-15 10:00:01.272 01[3109:32607] self.name = jerry say hello

問(wèn)題分析:可變屬性不用copy猾蒂,外部變量修改時(shí)均唉,對(duì)象的屬性也會(huì)跟著修改,因?yàn)楸举|(zhì)上它們指向的是同一塊內(nèi)存肚菠,顯然這不是我們?cè)敢饪吹降奶蚣蚤_(kāi)發(fā)中對(duì)于NSString, NSDictionary, NSArray等這種有可變非可變之分的屬性都建議使用copy,目的是為了讓本對(duì)象的屬性不受外界影響蚊逢,使用 copy 無(wú)論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本限嫌。

block 也經(jīng)常使用 copy 關(guān)鍵字,目的是為了將對(duì)象從棧中保存到堆中时捌。這么做的原因:這個(gè)問(wèn)題得先談到block本身是干嘛的怒医,block是一個(gè)能工作的代碼單元,可以在任何需要的時(shí)候被調(diào)用奢讨,本質(zhì)上是輕量級(jí)的匿名函數(shù)稚叹,可以作為其他函數(shù)的參數(shù)或者返回值。通常我們使用到block就是做了做回調(diào)用的拿诸,如果block在棧中扒袖,定義block的代碼一旦過(guò)了作用域則會(huì)被釋放掉,而后需要觸發(fā)回調(diào)的時(shí)候就會(huì)找不block亩码,為了讓block持久保存季率,用copy修飾將其由棧中移到堆中。

weak 和 assign的區(qū)別

相同點(diǎn):

  • 都會(huì)給被修飾的屬性指定一種“非擁有關(guān)系”描沟,為這種屬性賦值時(shí)即不保留新值也不釋放舊值飒泻,雖然持有對(duì)象,但是并不增加引用計(jì)數(shù)吏廉。

不同點(diǎn):

  • weak屬性所指的對(duì)象遭到摧毀時(shí)泞遗,屬性值也會(huì)清空(nil out)。
  • assign 的“設(shè)置方法”只會(huì)執(zhí)行針對(duì)“純量類型” (scalar type席覆,例如 CGFloat 或 NSlnteger 等)的簡(jiǎn)單賦值操作史辙。
  • assign 可以用非 OC 對(duì)象,而 weak 必須用于 OC 對(duì)象

知識(shí)補(bǔ)充:弱引用是怎么實(shí)現(xiàn)的
系統(tǒng)對(duì)于每一個(gè)有弱引用的對(duì)象,都維護(hù)一個(gè)hash 表來(lái)記錄它所有的 weak 屬性, 用 weak 指向的對(duì)象內(nèi)存地址作為 key聊倔,當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)為 0 時(shí)晦毙, 系統(tǒng)就會(huì)以對(duì)象地址為key在這個(gè) weak 表中搜索,找到對(duì)應(yīng) weak 屬性耙蔑,繼而置成 nil结序。

我們可以看出,弱引用的使用是有額外的開(kāi)銷的纵潦。雖然這個(gè)開(kāi)銷很小徐鹤,如果有些地方不是很需要弱引用的特性,就不應(yīng)該盲目使用弱引用邀层。

舉例:很多開(kāi)發(fā)者喜歡在手寫界面的時(shí)候返敬,將所有界面元素都設(shè)置成 weak 的,這與 Xcode 通過(guò) Storyboard或Xib拖拽生成的新變量是一致的寥院。但是這樣做并不合適:首先大部分 ViewController 的視圖對(duì)象的生命周期與 ViewController 本身是一致的劲赠,沒(méi)有必要額外做這個(gè)事情;其次弱引用可能會(huì)出現(xiàn)該對(duì)象剛被創(chuàng)建就被釋放秸谢;再者通過(guò)Storyboard或Xib拖拽生成的屬性默認(rèn)是weak修飾凛澎,這與蘋果之前的設(shè)計(jì)有關(guān),在 iOS6 之前應(yīng)用收到 Memory warning 時(shí)估蹄,系統(tǒng)會(huì)自動(dòng)調(diào)用當(dāng)前沒(méi)在界面上的 ViewController 的 viewDidUnload 方法塑煎,這些ViewController 的 View 會(huì)被 unLoad 掉,這個(gè)時(shí)候臭蚁,使用 weak 的視圖變量是有用的最铁,但是現(xiàn)在但是這個(gè)設(shè)計(jì)已經(jīng)被廢棄了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末垮兑,一起剝皮案震驚了整個(gè)濱河市冷尉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌系枪,老刑警劉巖雀哨,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異私爷,居然都是意外死亡雾棺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門当犯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)垢村,“玉大人割疾,你說(shuō)我怎么就攤上這事嚎卫。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拓诸,是天一觀的道長(zhǎng)侵佃。 經(jīng)常有香客問(wèn)我,道長(zhǎng)奠支,這世上最難降的妖魔是什么馋辈? 我笑而不...
    開(kāi)封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮倍谜,結(jié)果婚禮上迈螟,老公的妹妹穿的比我還像新娘。我一直安慰自己尔崔,他們只是感情好答毫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著季春,像睡著了一般洗搂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上载弄,一...
    開(kāi)封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天耘拇,我揣著相機(jī)與錄音,去河邊找鬼宇攻。 笑死惫叛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逞刷。 我是一名探鬼主播挣棕,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼亲桥!你這毒婦竟也來(lái)了洛心?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤题篷,失蹤者是張志新(化名)和其女友劉穎词身,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體番枚,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡法严,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葫笼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片深啤。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖路星,靈堂內(nèi)的尸體忽然破棺而出溯街,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布呈昔,位于F島的核電站挥等,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏堤尾。R本人自食惡果不足惜肝劲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望郭宝。 院中可真熱鬧辞槐,春花似錦、人聲如沸粘室。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)育特。三九已至丙号,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缰冤,已是汗流浹背犬缨。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棉浸,地道東北人怀薛。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像迷郑,于是被迫代替她去往敵國(guó)和親枝恋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 昨天端午節(jié),相信很多人都吃上了媽媽包的粽子我媽媽和別人聊天說(shuō)起包粽子霸妹,我不知道有多少人你們的媽媽是會(huì)包粽子的十电,但是...
    琉慧閱讀 463評(píng)論 0 0
  • 周末或者節(jié)假日鹃骂,公交車滿滿一車人,而且一天幾趟都爆滿的時(shí)候罢绽。人們會(huì)吃驚畏线,公交生意真好啊×技郏可是也會(huì)有淡季的時(shí)候寝殴,...
    咫尺為鄰閱讀 179評(píng)論 0 0
  • 今天上午看到劉老師發(fā)的信息蒿叠,說(shuō):“明天邀請(qǐng)十五名家長(zhǎng)進(jìn)校園進(jìn)講堂聽(tīng)課”,看了好興奮杯矩,終于有機(jī)會(huì)進(jìn)教室兩位老...
    其樂(lè)媽咪閱讀 207評(píng)論 0 0
  • 現(xiàn)在很多人年齡到了中年曼验,卻越來(lái)越困惑泌射,甚至開(kāi)始懷疑自己所過(guò)的生活是假的?小貝總結(jié)了人到中年的9種苦逼鬓照,看你都中了哪...
    分享貝閱讀 1,009評(píng)論 1 0
  • 短篇小說(shuō)集丨陳汐年 "好熔酷,就這樣吧,一切都聽(tīng)你的豺裆。" 李源一只手握住路邊的路燈拒秘,另一只手拿著手機(jī),發(fā)抖的力度和他說(shuō)...
    陳汐年閱讀 387評(píng)論 2 7