synthesize有什么作用?
當(dāng)定義了一系列的變量時,需要寫很多的getter和setter方法,而且它們的形式都是差不多的,所以Xcode提供了@property和@synthesize屬性,property用在 .h 頭文件中用作聲明桥滨,@synthesize用在.m 文件中用于實(shí)現(xiàn)。
在X-code4.5以前弛车,在.h中聲明完屬性之后齐媒,如:@property(nonatomic,assign) int age;
@property(nonatomic帅韧,assign) NSString *name;
需要在.m中寫上@synthesize int age;
@synthesize NSString *name;
系統(tǒng)會自動去實(shí)現(xiàn)setter和getter方法
而在X-code4.5之后里初,@synthesize就不需要再寫了,系統(tǒng)會直接去實(shí)現(xiàn)setter和getter方法忽舟。另外双妨,聲明完property屬性之后,會自動生成下劃線叮阅,如_age刁品、_name;如果不想要下劃線浩姥,那么就可以使用@synthesize去修飾挑随,例如,在.m中寫@synthesize age勒叠;那么_age就會變成age
2兜挨、NSString什么時候用copy,什么時候用strong
比如:
@property (retain,nonatomic) NSString *rStr;
@property (copy, nonatomic) NSString *cStr;
- (void)test:
{
NSMutableString *mStr = [NSMutableStringstringWithFormat:@"abc"];
self.rStr = mStr;
self.cStr = mStr;
NSLog(@"mStr:%p,%p", mStr,&mStr);
NSLog(@"retainStr:%p,%p", _rStr, &_rStr);
NSLog(@"copyStr:%p,%p", _cStr, &_cStr);
}
假如眯分,mStr對象的地址為0x11拌汇,也就是0x11是@“abc”的首地址,mStr變量自身在內(nèi)存中的地址為0x123弊决;
當(dāng)把mStr賦值給retain的rStr時噪舀,rStr對象的地址為0x11魁淳,rStr變量自身在內(nèi)存中的地址為0x124;rStr與mStr指向同樣的地址与倡,他們指向的是同一個對象@“abc”界逛,這個對象的地址為0x11,所以他們的值是一樣的纺座。
當(dāng)把mStr賦值給copy的cStr時息拜,cStr對象的地址為0x22,cStr變量自身在內(nèi)存中的地址0x125比驻;cStr與mStr指向的地址是不一樣的该溯,他們指向的是不同的對象,所以copy是深復(fù)制别惦,一個新的對象,這個對象的地址為0x22夫椭,值為@“abc”掸掸。
如果現(xiàn)在改變mStr的值:
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", _rStr);
NSLog(@"copyStr:%@", _cStr);
結(jié)果,
使用retain的字串rStr的值:@"abcde",
而使用copy的字串cStr的值:@"abc",
所以蹭秋,如果一般情況下扰付,我們都不希望字串的值跟著mStr變化,所以我們一般用copy來設(shè)置string的屬性仁讨。
如果希望字串的值跟著賦值的字串的值變化羽莺,可以使用strong,retain洞豁。
注意:上面的情況是針對于當(dāng)把NSMutableString賦值給NSString的時候盐固,才會有不同,如果是賦值是NSString對象丈挟,那么使用copy還是strong刁卜,結(jié)果都是一樣的,因?yàn)镹SString對象根本就不能改變自身的值曙咽,他是不可變的蛔趴。
把一個對象賦值給一個屬性變量,當(dāng)這個對象變化了例朱,如果希望屬性變量變化就使用strong屬性孝情,如果希望屬性變量不跟著變化,就是用copy屬性洒嗤。
由此可以看出:
對源頭是NSMutableString的字符串箫荡,retain僅僅是指針引用,增加了引用計數(shù)器烁竭,這樣源頭改變的時候菲茬,用這種retain方式聲明的變量(無論被賦值的變量是可變的還是不可變的),它也會跟著改變;而copy聲明的變量,它不會跟著源頭改變婉弹,它實(shí)際上是深拷貝睬魂。
對源頭是NSString的字符串,無論是retain聲明的變量還是copy聲明的變量镀赌,當(dāng)?shù)诙卧搭^的字符串重新指向其它的地方的時候氯哮,它還是指向原來的最初的那個位置,也就是說其實(shí)二者都是指針引用商佛,也就是淺拷貝喉钢。
另外說明一下,這兩者對內(nèi)存計數(shù)的影響都是一樣的良姆,都會增加內(nèi)存引用計數(shù)肠虽,都需要在最后的時候做處理。
其實(shí)說白了玛追,對字符串為啥要用這兩種方式税课?我覺得還是一個安全問題,比如聲明的一個NSString *str變量痊剖,然后把一個NSMutableString *mStr變量的賦值給它了韩玩,如果要求str跟著mStr變化,那么就用retain;如果str不能跟著mStr一起變化陆馁,那就用copy找颓。而對于要把NSString類型的字符串賦值給str,那兩都沒啥區(qū)別叮贩。不會影響安全性击狮,內(nèi)存管理也一樣
3.weak和assign有什么區(qū)別?
區(qū)別:
weak 只可以修飾對象妇汗。如果修飾基本數(shù)據(jù)類型帘不,編譯器會報錯
assign 可修飾對象,和基本數(shù)據(jù)類型杨箭。當(dāng)需要修飾類型時寞焙,MRC 時使用 unsafe_unretained。當(dāng)然互婿,unsafe_unretained 也可能產(chǎn)生野指針捣郊,所以它名字是“unsafe_”.
weak 不會產(chǎn)生野指針問題。因?yàn)閣eak修飾的對象釋放后引用計數(shù)值為0慈参,指針會自動被置 nil呛牲,之后再向該對象發(fā)消息也不會崩潰。weak 是安全的
assign 如果修飾對象驮配,會產(chǎn)生野指針問題娘扩;如果修飾基本數(shù)據(jù)類型是安全的着茸。修飾的對象釋放后,指針不會自動被置空琐旁,此時向?qū)ο蟀l(fā)消息會崩潰涮阔。
相同:都可以修飾對象類型,但是 assign 修飾對象會存在問題灰殴。
總結(jié):assign 適用基本數(shù)據(jù)類型敬特,不適用于引用類型。因?yàn)橹殿愋蜁环湃霔V形眨裱冗M(jìn)后出原則伟阔,由系統(tǒng)負(fù)責(zé)管理?xiàng)?nèi)存。而引用類型會被放入堆中掰伸,需要我們自己手動管理內(nèi)存或通過ARC管理
weak 適用 delegate 和 block 等引用類型皱炉,不會導(dǎo)致野指針問題,也不會循環(huán)引用碱工,非常安全
4.c 語言里的數(shù)組與 OC 數(shù)組的區(qū)別
OC 數(shù)組是一個對象娃承,有大量的方法,c 沒有都需要自己寫
c 數(shù)組刪除是需要后面往前移動怕篷,OC 數(shù)組自動處理
5.詳解枚舉 NS_OPTIONS 與 NS_ENUM的區(qū)別與格式
在蘋果的一篇官方文檔
《Adopting Modern Objective-C》 “適應(yīng)現(xiàn)代的 Objective-c” 中提及到使用 NS_ENUM 和 NS_OPTIONS 來聲明枚舉
NS_ENUM 用來聲明基于一般整形的枚舉,而 NS_OPTIONS 一般用來聲明基于位掩碼的聲明(bitmask)
NS_OPTIONS
typedef NS_OPTIONS(NSUInteger,UISwipeGestureRecognizerDirection){
UISwipeGestureRecognizerDirectionNone = 0,
UISwipeGestureRecognizerDirectionRight = 1 << 0,
UISwipeGestureRecognizerDirectionLeft = 1 << 1,
UISwipeGestureRecognizerDirectionUp = 1 << 2,
UISwipeGestureRecognizerDirectionUp = 1 << 2,
}
小括號中第一個為 NSUInteger 這個為固定值酗昼,第二個為枚舉類型廊谓,自己定義,大括號中枚舉基必須全部包含小括號的枚舉類型麻削,定義位移枚舉蒸痹,
UISwipeGestureRecognizer *swipeGR = [UISwipeGestureRecognizer alloc] init];
swipeGR.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLef;
typedef NS_ENUM(NSInteger,NSWritingDirection){
NSWritingDirectionNatural = -1,
NSWritingDirectionLeftToRight = 0,
NSWritingDirectionRightToLeft = 1,
}
小括號中第一個為 NSInteger 這個為固定值,定義通用枚舉