iOS中的property屬性

MRC與ARC

談property屬性之前需要引入OC的兩種內(nèi)存管理機(jī)制
MRC:全稱Manual Reference Counting 即手動(dòng)引用計(jì)數(shù)器
ARC:全稱Automatic Reference Counting 即自動(dòng)引用計(jì)數(shù)器叮阅,
自從ARC在iOS5被引入后椭蹄,經(jīng)過多個(gè)版本的驗(yàn)證蕉堰,MRC目前已經(jīng)成為了歷史加勤,下文將主要講解ARC下的關(guān)鍵字

Property屬性含有以下修飾符

  • 原子性:nonatomic赞季,atomic
  • 讀寫:readwrite, readonly, writeonly
  • 內(nèi)存:weak,assign翰守,unsafe_unretained则吟,strong,retain皇忿,copy畴蹭,

atomic vs nonatomic

atomic
  • 默認(rèn)關(guān)鍵字
  • 對對象操作屬于原子性,即只有一個(gè)線程可以同時(shí)訪問這個(gè)實(shí)例鳍烁,是線程安全的
  • 實(shí)際上使用頻率很低叨襟,因?yàn)槠涫褂猛芥i,開銷較大幔荒,損失性能
nonatomic:
  • 對對象操作屬于非原子性糊闽,實(shí)例可以被多個(gè)線程訪問,所以無法保證多線程狀態(tài)下的安全性爹梁,屬于非線程安全
  • 效率要比atomic高
  • 在iOS開發(fā)中被廣泛使用

readwrite VS readonly VS writeonly

readwrite
  • 默認(rèn)屬性
  • 自動(dòng)生成setter右犹,getter方法
  • 讀寫屬性,可以對實(shí)例進(jìn)行讀寫
readonly
  • 自動(dòng)生成getter方法
  • 只讀屬性卫键,只能對實(shí)例進(jìn)行讀取
writeonly
  • 自動(dòng)生成setter方法 從來沒用過
  • 只寫屬性傀履,只能對實(shí)例進(jìn)行寫入
自定義getter虱朵,setter方法

getter=<name>
setter=<name>

@interface ViewController ()
@property(strong,readonly,getter=gA)NSString *A;
@property(strong,getter=gB,setter=sB:)NSString *B;
@property (strong,getter=gC)NSString *C;
@property NSString *D;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    _A = @"A";
    NSLog(@"A:%@",[self gA]);
    
    [self sB:@"B"];
    NSLog(@"B:%@",[self gB]);
    
    [self setC:@"C"];
    NSLog(@"C:%@",[self gC]);
    
    [self setD:@"D"];
    NSLog(@"D:%@",[self D]);
    // Do any additional setup after loading the view.
}
@end

assign VS weak VS unsafe_unretained

  • assign 可以修飾基本數(shù)據(jù)類型莉炉,也可以修飾引用類型
  • weak 用于修飾引用類型
  • unsafe_unretained 用于修飾引用類型
  • 三者都可以修飾引用類型
  • 都為弱引用,即不增加引用計(jì)數(shù)器計(jì)數(shù)
  • assign常用于修飾基本數(shù)據(jù)類型碴犬,修飾對象時(shí)絮宁,當(dāng)對象釋放,指針不會(huì)置空服协,會(huì)生成野指針绍昂,向?qū)ο蟀l(fā)送消息會(huì)引發(fā)崩潰
  • weak修飾引用類型,當(dāng)對象釋放后偿荷,指針會(huì)被設(shè)置為nil窘游,向?qū)ο蟀l(fā)送消息不會(huì)引發(fā)崩潰
  • unsafe_unretained與assign的區(qū)別在于,其只修飾引用類型跳纳,也會(huì)生成野指針
為什么UI控件和delegate用weak
  • 當(dāng)控制器持有的view addsubView時(shí)候會(huì)強(qiáng)引用subview忍饰,所以修飾subview時(shí)使用weak就可以了
  • delegate同理,拿tableview舉例寺庄,addsubview時(shí)控制器已經(jīng)強(qiáng)引用了tableview艾蓝,如果tableview的delegate還用strong力崇,則會(huì)造成循環(huán)引用

strong VS retain VS copy

  • strong 用于引用類型,強(qiáng)引用赢织,引用計(jì)數(shù)器+1亮靴, strong 用于ARC,retain用于MRC于置,默認(rèn)屬性
  • retain 用于引用類型茧吊,強(qiáng)引用,引用計(jì)數(shù)器+1俱两,retain用于MRC
  • copy 會(huì)在內(nèi)存中拷貝對象饱狂,分為深拷貝,淺拷貝
驗(yàn)證下strong是否為默認(rèn)屬性
@interface ViewController ()
@property(nonatomic,weak)Person *s;
@property(nonatomic)Person *p;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    
    Person *temp = [Person new];
    self.s = temp;
    self.p = temp;
    temp = nil;
    NSLog(@"對象內(nèi)存地址:%p %p",_s,_p);
    _p = nil;
    NSLog(@"對象內(nèi)存地址:%p %p",_s,_p);
    // Do any additional setup after loading the view.
}
@end

結(jié)論:temp置空宪彩,s休讳,p仍舊存在,即引用計(jì)數(shù)器已+1尿孔,
p置空后俊柔,s也為空,因?yàn)閟是weak活合,若引用

copy的深拷貝與淺拷貝

當(dāng)copy修飾不可變類型對象時(shí)雏婶,如NSString,NSDictionary白指,NSArray留晚,其實(shí)發(fā)生的是淺拷貝,即copy = strong

    NSString *temp = @"FFF";
    NSString *str = [temp copy];//淺拷貝告嘲,兩個(gè)指針指向同一塊內(nèi)存空間
    NSLog(@"%p %p",temp,str);//0x102924078 0x102924078
    NSLog(@"%@ %@",temp,str);//FFF FFF
    temp = @"TTT";//temp指向的內(nèi)存空間發(fā)生改變错维,str仍舊指向FFF的內(nèi)存空間
    NSLog(@"%p %p",temp,str);//0x1029240d8(改變) 0x102924078
    NSLog(@"%@ %@",temp,str);//TTT FFF

當(dāng)copy修飾可變類型對象時(shí),如NSMutableString橄唬,NSMutableArray赋焕,NSMutableDictionary,發(fā)生的單層深拷貝仰楚,其他層淺拷貝

    Person *person = [Person new];
    person.age = @"16";
    NSMutableArray <Person *>*temp = [NSMutableArray arrayWithObjects:person, nil];
    NSMutableArray <Person *>*arr = [temp copy];//數(shù)組拷貝隆判,內(nèi)部對象淺拷貝
    NSLog(@"%p %p",temp,arr);//0x60000350b630 0x60000397c740,數(shù)組對象發(fā)生了深拷貝
    NSLog(@"%@ %@",temp,arr); // <Person: 0x60000397c720> <Person: 0x60000397c720> 數(shù)組內(nèi)的對象發(fā)生了淺拷貝
    NSLog(@"%@ %@",temp[0].age,arr[0].age);//16 16
    person.age = @"18";
    NSLog(@"%@ %@",temp[0].age,arr[0].age);//18 18 因?yàn)闇\拷貝,所以Person對象發(fā)生改變后僧界,所有數(shù)組內(nèi)的值都發(fā)生了改變
    Person *crash = [Person new];
    crash.age = @"19";
    [temp addObject:crash];
    NSLog(@"%ld %ld",temp.count,arr.count);//2 1 數(shù)組發(fā)生變化
    [arr addObject:crash];//會(huì)崩潰侨嘀,因?yàn)閏opy出的數(shù)組對象為不可變的數(shù)組,NSMutableDictionary捂襟,NSMutableString同理
建議用copy修飾有對應(yīng)可變類型子類的對象

NSString/NSMutableString,NSArray/NSMutableArray,NSDictionary/NSMutableDictionary

     @interface Person : NSObject
     @property(nonatomic, strong)NSString *age;
     @end

    Person *person = [Person new];
    NSMutableString *s = [[NSMutableString alloc] initWithString:@"A"];
    //將可變字符串賦值給age
    person.age = s;
    //輸出的地址和內(nèi)容均一致
    NSLog(@"%p %p %@ %@", person.age, s, person.age, s);
    //修改可變字符串s
    [s appendString:@"B"];
    //再次輸出person.name被影響 從A變成了AB
    NSLog(@"%p %p %@ %@", person.age, s, person.age, s);
如果確定給NSString賦值的對象不是NSMutableString咬腕,建議用strong
  • 原因是copy過程中有一個(gè)if ([str isMemberOfClass:[str class]])判斷
    當(dāng)項(xiàng)目過大時(shí),存在性能損耗
Block用copy修飾笆豁,還是strong修飾
  • block創(chuàng)建時(shí)是在棧中郎汪,超出生命周期后就會(huì)被系統(tǒng)釋放掉赤赊,引發(fā)crash,用copy修飾煞赢,會(huì)拷貝一份到堆中抛计。其實(shí)用strong修飾也是可以因?yàn)槿耘f會(huì)執(zhí)行copy,算是xcode人性化的一面
block代碼塊內(nèi)self為什么用weak
  • block放入堆中照筑,會(huì)被self持有吹截,在代碼塊中需要用weak聲明的self,防止循環(huán)引用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凝危,一起剝皮案震驚了整個(gè)濱河市波俄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛾默,老刑警劉巖懦铺,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異支鸡,居然都是意外死亡冬念,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門牧挣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來急前,“玉大人,你說我怎么就攤上這事瀑构●烧耄” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵寺晌,是天一觀的道長世吨。 經(jīng)常有香客問我,道長折剃,這世上最難降的妖魔是什么另假? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任像屋,我火速辦了婚禮怕犁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘己莺。我一直安慰自己奏甫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布凌受。 她就那樣靜靜地躺著阵子,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胜蛉。 梳的紋絲不亂的頭發(fā)上挠进,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天色乾,我揣著相機(jī)與錄音,去河邊找鬼领突。 笑死暖璧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的君旦。 我是一名探鬼主播澎办,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼金砍!你這毒婦竟也來了局蚀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤恕稠,失蹤者是張志新(化名)和其女友劉穎琅绅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹅巍,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奉件,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了昆著。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片县貌。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凑懂,靈堂內(nèi)的尸體忽然破棺而出煤痕,到底是詐尸還是另有隱情,我是刑警寧澤接谨,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布摆碉,位于F島的核電站,受9級特大地震影響脓豪,放射性物質(zhì)發(fā)生泄漏巷帝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一扫夜、第九天 我趴在偏房一處隱蔽的房頂上張望楞泼。 院中可真熱鬧,春花似錦笤闯、人聲如沸堕阔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽超陆。三九已至,卻和暖如春浦马,著一層夾襖步出監(jiān)牢的瞬間时呀,已是汗流浹背张漂。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谨娜,地道東北人鹃锈。 一個(gè)月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像瞧预,于是被迫代替她去往敵國和親屎债。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

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