1 @property本質(zhì)
- @property關(guān)鍵字是xcode編譯器的一個(gè)編譯特性扣墩,它幫我們做了很多事
//例如Person類下的 @property (nonatomic, copy) NSString *name;
// 編譯器干的活
// .h中
@interface Person{
// 聲明成員變量
@protected
NSString *_name;
}
// name的getter和setter方法的聲明
- (NSString *)name;
- (void)setName:(NSString *)name;
@end
// .m中
@implementation Person
// 實(shí)現(xiàn)getter和setter方法
- (NSString *)name{
return _name;
}
- (void)setName:(NSString *)name{
_name = [name ];
}
@end
補(bǔ)充:
@synthesize name = _name;
是配合@property使用的泳赋,意思是在.m文件中的_name是對(duì)應(yīng)叫做name的property屬性砂豌。當(dāng)我們?cè)?m文件中將setter和getter方法都重寫的時(shí)候吐辙,需要加這個(gè)聲明间唉,否則_name在.m中是找不到的會(huì)報(bào)錯(cuò)啥繁。更深層次的本質(zhì)府瞄,就需要runtime的知識(shí)了托猩,可以參考
2 property屬性的關(guān)鍵字(ARC環(huán)境下)
-
1)關(guān)鍵字總結(jié)
- 主要分為4類印蓖,原子性、內(nèi)存管理語(yǔ)義京腥、讀寫權(quán)限赦肃、方法名
- 原子性:
atomic
、nonatomic
- 讀寫權(quán)限:
readwrite
、readonly
- 內(nèi)存管理語(yǔ)義:
assign
他宛、strong
船侧、weak
、copy
- 方法名:
getter=<name>
堕汞,setter=<name>
- ARC環(huán)境下勺爱,不顯示指定任何關(guān)鍵字的時(shí)候,對(duì)于基本數(shù)據(jù)類型默認(rèn)關(guān)鍵字是atomic讯检、readwrite琐鲁、assign,而對(duì)于普通的OC對(duì)象默認(rèn)是atomic人灼、readwrite围段、strong
-
2)關(guān)鍵字之間的區(qū)分
-
assign與weak
- assign主要用于基本數(shù)據(jù)類型、枚舉投放、結(jié)構(gòu)體等等奈泪,主要進(jìn)行賦值,
- weak是對(duì)對(duì)象的弱引用灸芳,對(duì)于引用的對(duì)象涝桅,不會(huì)增加它的內(nèi)存引用計(jì)數(shù),主要用于防止循環(huán)引用烙样; weak修飾的對(duì)象釋放掉后冯遂,weak屬性值會(huì)被置成nil,防止野指針谒获。
-
strong與copy
- strong:對(duì)于對(duì)象的強(qiáng)引用蛤肌,會(huì)增加對(duì)象的內(nèi)存引用計(jì)數(shù)
- copy:有的時(shí)候我們引用某個(gè)對(duì)象,但是并不希望這個(gè)對(duì)象的數(shù)據(jù)受外部的干擾批狱,這個(gè)時(shí)候我們就需要使用copy了裸准,就是創(chuàng)建一個(gè)對(duì)象的副本,當(dāng)我們操作這個(gè)副本的時(shí)候不會(huì)影響原來(lái)的對(duì)象赔硫,同時(shí)原來(lái)的對(duì)象的改變炒俱,也不會(huì)影響到我們擁有的這個(gè)副本。copy有深復(fù)制和淺復(fù)制爪膊,深復(fù)制是創(chuàng)建出一個(gè)新的對(duì)象向胡,淺復(fù)制是增加對(duì)原有對(duì)象的引用計(jì)數(shù)。
-
3 property拓展
-
1) protocol和category中如何使用property
- protocol中使用property惊完,主要是聲明屬性的getter和setter方法,使用這個(gè)的目的是希望遵守protocol協(xié)議的對(duì)象能實(shí)現(xiàn)該屬性
- category中使用@porperty也只會(huì)生成屬性的getter和setter方法的聲明处硬,如果我們真的需要給 category 增加屬性的實(shí)現(xiàn),需要借助于運(yùn)行時(shí)的兩個(gè)函數(shù)
objc_setAssociatedObject
,objc_getAssociatedObject
-
2)weak屬性如何實(shí)現(xiàn)
- 要實(shí)現(xiàn) weak 屬性小槐,首先要搞清楚 weak 屬性的特點(diǎn):
weak 此特質(zhì)表明該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)。為這種屬性設(shè)置新值時(shí),設(shè)置方法既不保留新值凿跳,也不釋放舊值件豌。此特質(zhì)同 assign 類似, 然而在屬性所指的對(duì)象遭到摧毀時(shí)控嗜,屬性值也會(huì)清空(nil out)茧彤。 - 那么 runtime 如何實(shí)現(xiàn) weak 變量的自動(dòng)置nil?
runtime 對(duì)注冊(cè)的類疆栏, 會(huì)進(jìn)行布局曾掂,對(duì)于 weak 對(duì)象會(huì)放入一個(gè) hash 表中。 用 weak 指向的對(duì)象內(nèi)存地址作為 key壁顶,當(dāng)此對(duì)象的引用計(jì)數(shù)為0的時(shí)候會(huì) dealloc珠洗,假如 weak 指向的對(duì)象內(nèi)存地址是a,那么就會(huì)以a為鍵若专, 在這個(gè) weak 表中搜索许蓖,找到所有以a為鍵的 weak 對(duì)象,從而設(shè)置為 nil调衰。
- 要實(shí)現(xiàn) weak 屬性小槐,首先要搞清楚 weak 屬性的特點(diǎn):
-3)copy的拓展
-
自定義的類如何實(shí)現(xiàn)copy
需聲明該類遵從 NSCopying 協(xié)議
-
實(shí)現(xiàn) NSCopying 協(xié)議膊爪。該協(xié)議只有一個(gè)方法:
- (id)copyWithZone:(NSZone *)zone;
- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex { if(self = [super init]) { _name = [name copy]; _age = age; _sex = sex; _friends = [[NSMutableSet alloc] init]; } return self; } - (id)copyWithZone:(NSZone *)zone { CYLUser *copy = [[[self class] allocWithZone:zone] initWithName:_name age:_age sex:_sex]; copy->_friends = [_friends mutableCopy]; return copy; }
-
copy屬性的setter方法的重寫
- release舊值,copy新值
- (void)setName:(NSString *)name { _name = [name copy]; }
-
非集合類與集合類的copy區(qū)別
在非集合類對(duì)象中:對(duì) immutable 對(duì)象進(jìn)行 copy 操作嚎莉,是指針復(fù)制米酬,mutableCopy 操作時(shí)內(nèi)容復(fù)制;對(duì) mutable 對(duì)象進(jìn)行 copy 和 mutableCopy 都是內(nèi)容復(fù)制萝喘。用代碼簡(jiǎn)單表示如下:
[immutableObject copy] // 淺復(fù)制
[immutableObject mutableCopy] //深復(fù)制
[mutableObject copy] //深復(fù)制
[mutableObject mutableCopy] //深復(fù)制-
集合類對(duì)象的copy
主要是2個(gè)注意點(diǎn)淮逻,僅僅集合對(duì)象的拷貝,還是拷貝集合對(duì)象及其內(nèi)部的元素NSMutableArray *array = [NSMutableArray arrayWithObjects: [NSMutableString stringWithString:@"a"],@"b",@"c",nil]; // 僅僅復(fù)制集合阁簸,里面的元素不會(huì)改變 NSArray *copyArray = [array copy]; NSMutableArray *mCopyArray = [array mutableCopy]; // 深度復(fù)制爬早,集合與里面的元素都會(huì)復(fù)制一份 NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES];