最近在看到一些面試題太雨,問的是代碼規(guī)范的相關(guān)問題籽暇,記錄一下個(gè)人的見解动知,有錯(cuò)誤的地方望指正
修改為:
typedef ENUM(NSInteger, UserSex){
UserSexMan,
UserSexWoman
}UserSex;
@interFace UserModel : NSObject //注意冒號之間的空格
@property (nonatomic, copy) NSString *userName; //NSString用copy修飾
@property (nonatomic, assign) NSInteger userAge; //保持nonatomic在前,另外個(gè)人喜歡用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
/*
*相同點(diǎn)
*都可以作為方法的返回類型
*不同點(diǎn)
*instancetype可以返回和方法所在類相同類型的對象绵估,id只能返回未知類型的對象;
*instancetype只能作為返回值卡骂,不能像id那樣作為參數(shù)国裳,比如下面的寫法:
*/
- (void)didLogin; // do or did? login是一個(gè)單詞
看完上面的問題突然想起其他幾個(gè)問題:
1.assgin和weak的區(qū)別:
assign適用于基本數(shù)據(jù)類型,weak是適用于NSObject對象全跨,并且是一個(gè)弱引用
assign其實(shí)也可以用來修飾對象缝左。那么我們?yōu)槭裁床挥盟揎棇ο竽兀恳驗(yàn)楸籥ssign修飾的對象(一般編譯的時(shí)候會產(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)對它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次時(shí)也會使用weak后豫。比如:自定義 IBOutlet控件屬性一般也使用weak暂筝,當(dāng)然也可以使用strong
2.strong和copy的區(qū)別
- strong 與copy都會使引用計(jì)數(shù)加1,但strong是兩個(gè)指針指向
同一個(gè)
內(nèi)存地址硬贯,copy會在內(nèi)存里拷貝
一份對象焕襟,兩個(gè)指針指向不同的內(nèi)存地址。個(gè)人理解類似于淺拷貝和深拷貝的區(qū)別
3.__block與__weak的區(qū)別
- 代碼中
__block
是用來修飾一個(gè)變量饭豹,這個(gè)變量就可以在block中被修鸵赖,__block
:使用__block
修飾的變量在block代碼塊中會被retain(ARC下會retain,MRC下不會retain) -
__weak
:使用__weak
修飾的變量不會在block代碼塊中被retain 同時(shí)拄衰,在ARC下它褪,要避免block出現(xiàn)循環(huán)引用 __weak typedof(self)weakSelf = self;
4. block變量定義時(shí)為什么用copy?block是放在哪里的翘悉?
- block本身是像對象一樣可以retain茫打,和release。但是妖混,block在創(chuàng)建的時(shí)候老赤,它的內(nèi)存是分配在棧(stack)上,可能被隨時(shí)回收制市,而不是在堆(heap)上抬旺。他本身的作于域是屬于創(chuàng)建時(shí)候的作用域,一旦在創(chuàng)建時(shí)候的作用域外面調(diào)用block將導(dǎo)致程序崩潰祥楣。通過copy可以把block拷貝(copy)到堆开财,保證block的聲明域外使用。
參考資料
文/九零猴VS久林(簡書作者)
NSString(NSArray误褪、NSURLReques)到底用copy還是strong
- 對于copy修飾的屬性來說责鳍,若賦值源是NSString、NSArray兽间、NSURLRequest三者其中之一历葛,復(fù)制時(shí)是shadow copy(淺復(fù)制),即地址相同渡八,類型相同
- 來源若是NSMutableString啃洋,NSMutableArray传货,NSMutableURLRequest之一
1.使用strong修飾的,賦值后宏娄,地址相同问裕,類型也相同
2.使用copy修飾的,會復(fù)制賦值源所生成的對象孵坚,復(fù)制后粮宛,地址不同,而來源是NSMutableArray的卖宠,甚至連類型也不同(__NSArrayI
與__NSArrayM
)巍杈,說明復(fù)制時(shí)都是deep copy(深復(fù)制)
總得來說:
1.如果來源是NSString,使用copy或strong沒有區(qū)別扛伍。
2.如果來源是NSMutableString筷畦,NSString對象會因其改變而改變。若使用copy刺洒,因?yàn)槭巧顝?fù)制鳖宾,產(chǎn)生了一個(gè)新的對象,就可以避免以上情況逆航。也就是說如果我們不想因?yàn)镹SString類型屬性會對來源進(jìn)行修改鼎文,我們可以用copy來修飾
更新:github上的參考答案