最近在看到一些面試題,問的是代碼規(guī)范的相關(guān)問題,記錄一下個人的見解,有錯誤的地方望指正
修改為:
typedef ENUM(NSInteger, UserSex){
UserSexMan,
UserSexWoman
}UserSex;
@interFace UserModel : NSObject //注意冒號之間的空格
@property (nonatomic, copy) NSString *userName; //NSString用copy修飾
@property (nonatomic, assign) NSInteger userAge; //保持nonatomic在前,另外個人喜歡用NSInteger,適配32位和64位?
@property (nonatomic, assign) UserSex userSex;
- (instancetype)initUserModelWithUserName:(NSString *)name age:(NSInteger)age;
// 這里我用instancetype取代id
// 未知類型的的對象可以用id關(guān)鍵字表示
// instancetype的作用,就是使那些非關(guān)聯(lián)返回類型的方法返回所在類的類型。
// 后面不用with修飾
// 具體可以參考:http://blog.csdn.net/kuizhang1/article/details/18048829
/*
*相同點
*都可以作為方法的返回類型
*不同點
*instancetype可以返回和方法所在類相同類型的對象,id只能返回未知類型的對象;
*instancetype只能作為返回值,不能像id那樣作為參數(shù),比如下面的寫法:
*/
- (void)didLogin; // do or did? login是一個單詞
看完上面的問題突然想起其他幾個問題:
1.assgin和weak的區(qū)別:
assign適用于基本數(shù)據(jù)類型,weak是適用于NSObject對象,并且是一個弱引用
assign其實也可以用來修飾對象。那么我們?yōu)槭裁床挥盟揎棇ο竽兀恳驗楸籥ssign修飾的對象(一般編譯的時候會產(chǎn)生警告:Assigning retained object to unsafe property; object will be released after assignment)在釋放之后,指針的地址還是存在的,也就是說指針并沒有被置為
nil
,造成野指針。對象一般分配在堆上的某塊內(nèi)存,如果在后續(xù)的內(nèi)存分配中,剛好分到了這塊地址,程序就會崩潰掉。基礎(chǔ)數(shù)據(jù)類型一般分配在棧上,棧的內(nèi)存會由系統(tǒng)自己自動處理,不會造成野指針,所以可以用assign修飾
weak修飾的對象在釋放之后,指針地址會被置為
nil
。所以現(xiàn)在一般弱引用就是用weak。weak使用場景:
1.ARC中避免循環(huán)引用
,比如delegate就是用weak修飾
2.自身已經(jīng)對它進行一次強引用,沒有必要再強引用一次時也會使用weak。比如:自定義 IBOutlet控件屬性一般也使用weak,當然也可以使用strong
2.strong和copy的區(qū)別
- strong 與copy都會使引用計數(shù)加1,但strong是兩個指針指向
同一個
內(nèi)存地址,copy會在內(nèi)存里拷貝
一份對象,兩個指針指向不同的內(nèi)存地址。個人理解類似于淺拷貝和深拷貝的區(qū)別
3.__block與__weak的區(qū)別
- 代碼中
__block
是用來修飾一個變量,這個變量就可以在block中被修,__block
:使用__block
修飾的變量在block代碼塊中會被retain(ARC下會retain,MRC下不會retain) -
__weak
:使用__weak
修飾的變量不會在block代碼塊中被retain 同時,在ARC下,要避免block出現(xiàn)循環(huán)引用 __weak typedof(self)weakSelf = self;
4. block變量定義時為什么用copy?block是放在哪里的?
- block本身是像對象一樣可以retain,和release。但是,block在創(chuàng)建的時候,它的內(nèi)存是分配在棧(stack)上,可能被隨時回收,而不是在堆(heap)上。他本身的作于域是屬于創(chuàng)建時候的作用域,一旦在創(chuàng)建時候的作用域外面調(diào)用block將導(dǎo)致程序崩潰。通過copy可以把block拷貝(copy)到堆,保證block的聲明域外使用。
參考資料
文/九零猴VS久林(簡書作者)
NSString(NSArray、NSURLReques)到底用copy還是strong
- 對于copy修飾的屬性來說,若賦值源是NSString、NSArray、NSURLRequest三者其中之一,復(fù)制時是shadow copy(淺復(fù)制),即地址相同,類型相同
- 來源若是NSMutableString,NSMutableArray,NSMutableURLRequest之一
1.使用strong修飾的,賦值后,地址相同,類型也相同
2.使用copy修飾的,會復(fù)制賦值源所生成的對象,復(fù)制后,地址不同,而來源是NSMutableArray的,甚至連類型也不同(__NSArrayI
與__NSArrayM
),說明復(fù)制時都是deep copy(深復(fù)制)
總得來說:
1.如果來源是NSString,使用copy或strong沒有區(qū)別。
2.如果來源是NSMutableString,NSString對象會因其改變而改變。若使用copy,因為是深復(fù)制,產(chǎn)生了一個新的對象,就可以避免以上情況。也就是說如果我們不想因為NSString類型屬性會對來源進行修改,我們可以用copy來修飾
更新:github上的參考答案