Objective-C代碼規(guī)范個人的小總結(jié)

最近在看到一些面試題,問的是代碼規(guī)范的相關(guān)問題,記錄一下個人的見解,有錯誤的地方望指正

Paste_Image.png

修改為:

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上的參考答案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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