2.對象、消息闺金、運行期

第6條 理解屬性這一概念


以上也是Category 為何不能添加成員變量的原因逾滥,更多參考:
http://quotation.github.io/objc/2015/05/21/objc-runtime-ivar-access.html
http://www.reibang.com/p/2d63477c4d46

  • __unsafe_unretained 跟 assign 類似,只不過它是修飾對象的败匹,而 assign 是修飾基本類型的匣距。兩者修飾的屬性在釋放時,都不會自動將屬性值置為 nil哎壳。

  • 修飾NSString 的時候最好用 copy,原因如下:

@property (retain) NSString *name;
- (void)xxx
{
    NSMutableString *mName = [@"mName" mutableCopy];
    self.name = mName;
    //接下來尚卫,如果我修改了 mName(比如在 mName上拼字符串)归榕,那么self.name也會跟著修改,
    //但開發(fā)者可能會認(rèn)為 self.name 只是個 NSString 的不可變字符串吱涉,不應(yīng)該被修改刹泄,但其實卻是個 NSMutableString外里。
    //若用了copy就不會發(fā)生這種情況。
}

  • 如果屬性用 copy 修飾了特石,在 init 方法里要對應(yīng)的用 copy 賦值盅蝗,如:
@property (copy) NSString *name;

- (instancetype)initWithName:(NSString *)newName
{
    self = [super init];
    if (self) {
        _name = [newName copy]; //要用copy賦值
    }
    return self;
}

  • 如果設(shè)置了 readonly ,可以只在 init 方法里賦值(如下代碼)姆蘸,其他地方再調(diào)用 self.name = xxx 賦值的話墩莫,就會報錯了。
@property (copy, readonly) NSString *name;

- (instancetype)initWithName:(NSString *)newName
{
    self = [super init];
    if (self) {
        _name = [newName copy];
    }
    return self;
}
  • atomic 和 nonatomic 的區(qū)別


第7條 在對象內(nèi)部盡量直接訪問成員變量

  • 在對象內(nèi)部逞敷,讀取的時候盡量用成員變量(惰性初始化除外狂秦,如下代碼),賦值的時候盡量用屬性推捐。
    原因:
    1. 讀取時裂问,直接訪問成員變量,速度會比較快牛柒,
    2. 但是如果賦值時堪簿,如果直接訪問成員變量就繞過了內(nèi)存管理機(jī)制,比如 copy 修飾了一個屬性皮壁,若直接給成員變量賦值椭更,就會 retain 而不會 copy 了。
    3. 直接訪問成員變量闪彼,不會觸發(fā) KVO甜孤。
    4. 用屬性,方便在 setter 方法里打斷點調(diào)試畏腕。
  • 在 init 和 dealloc 中缴川,盡量直接使用成員變量讀寫數(shù)據(jù)。
// 惰性初始化
- (Student *)student 
{
    if (!_ student) {
        _ student = [Student new];
    }
    return _ student;
}

第8條 理解“對象等同性”這個概念

NSObject 的判斷倆對象是否相同的方法 isEqual:- (NSUInteger)hash 的關(guān)系:
若用 isEqual: 判斷倆對象相等描馅,則 hash 一定相同把夸,但 hash 相同,isEqual: 判斷不一定相等铭污。

  • hash函數(shù)如何編寫(未讀懂)
  • NSArray 調(diào)用 isEqual: 的實現(xiàn)原理: 先判斷個數(shù)是否相同恋日,若相同,每一項調(diào)用isEqual:判斷是否相同嘹狞。
  • NSSet (集合)是一種哈希表岂膳,運用散列算法,查找集合中的元素比數(shù)組速度更快磅网,但是它沒有順序谈截。集合中的數(shù)據(jù)是唯一的,比如我存入倆相同的字符串,集合里只會有一個簸喂。

第9條 以“類族(類簇)模式”隱藏實現(xiàn)細(xì)節(jié)

類族一般沒有 init 方法毙死,只有一些工廠方法,它只是一個抽象的基類喻鳄,中間的實現(xiàn)過程都隱藏了扼倘。例如UIButton,初始化沒有init除呵,而是用 buttonWithType:再菊,其內(nèi)部可能是每個類型聲明了一個新的類(只是舉個UIButton的例子,UIButton實際并不是類族)竿奏。
collection類(集合類)一般都是類族袄简,包括 NSArray、NSSet和NSDictionary等泛啸,NSString绿语、NSNumber等也是類族,以下結(jié)果返回的是NO:

NSArray *arr = [NSArray arrayWithObjects:@"abc", nil];
  if ([arr isMemberOfClass:[NSArray class]])
  {
      NSLog(@"YES");
  }
  else {
      NSLog(@"NO");
  }

第10條 在既有類中使用關(guān)聯(lián)對象存儲自定義數(shù)據(jù)

#import <objc/runtime.h>

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /** 和 assgin 等效 */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /** strong候址、nonatomic */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /** copy吕粹、nonatomic */
    OBJC_ASSOCIATION_RETAIN = 01401,       /** strong、atomic */
    OBJC_ASSOCIATION_COPY = 01403          /**< copy岗仑、atomic */
};

//設(shè)置關(guān)聯(lián)
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) 

//獲取關(guān)聯(lián)的對象值
id objc_getAssociatedObject(id object, const void *key)

//移除指定對象的全部關(guān)聯(lián)對象
void objc_removeAssociatedObjects(id object)  

UIAlertView 的 delegate 傳值的時候匹耕,如果傳一個 tag 還好說,如果是傳多個參數(shù)荠雕,要么用一個子類繼承于 UIAlertView稳其,設(shè)置多個屬性,要么就用關(guān)聯(lián)對象炸卑。

第11條 理解 objc_msgSend的作用

C語言是靜態(tài)綁定既鞠,若不考慮內(nèi)聯(lián)(inline),當(dāng)你調(diào)用一個函數(shù)的時候盖文,編譯的時候編譯器就知道存在這個函數(shù)了嘱蛋。

// OC 中的語句
id retureValue = [obj messageName:parameter];

// 轉(zhuǎn)成C語言后的原型
id retureValue = objc_msgSend(obj, @selector(messageName:), parameter);

objc_msgSend 方法會在 接收者(obj)中尋找方法列表,如果找不到五续,就在從父類依次往上找洒敏,一直找到NSObject,如果還沒找到疙驾,就開始消息轉(zhuǎn)發(fā)凶伙。這個過程中,objc_msgSend并非每次都會查找它碎,每個類會有一個緩存镊靴,這樣大大提高了查找效率铣卡。

objc_msgSend_stret
objc_msgSend_fpret
objc_msgSendSuper
...
還有些內(nèi)容太抽象,此處省略偏竟。

第12條 理解消息轉(zhuǎn)發(fā)機(jī)制

上條介紹的消息傳遞,傳遞過程中找不到對應(yīng)的方法敞峭,就會執(zhí)行消息轉(zhuǎn)發(fā)踊谋。消息轉(zhuǎn)發(fā)分為兩大階段:

  1. 動態(tài)解析:詢問接收者所屬的類,能否動態(tài)添加方法旋讹。
  2. 完整的消息轉(zhuǎn)發(fā):系統(tǒng)請求接收者用其他方式處理消息殖蚕。又分為倆階段(就是倆回調(diào)方法),首先沉迹,先看下其他類能否處理該消息睦疫,若沒有,系統(tǒng)會把與消息有關(guān)的全部細(xì)節(jié)封裝給NSInvocation對象中鞭呕,再給接收者蛤育,最后一次機(jī)會。

代碼示例葫松,建了一個EOCAutoDictionary的類瓦糕,可以用該類任意存值。如:

    ECOAutoDictionary *a = [ECOAutoDictionary new];
    a.data = [NSDate date];
    NSLog(@"a.data-------%@", a.date);

第13條 用“方法調(diào)配技術(shù)”調(diào)試“黑盒方法”

method swizzling腋么,一般用于打印一個系統(tǒng)方法日志咕娄,最好不要濫用,否則會讓代碼不易被讀懂珊擂。

第14條 理解“類對象”的用意

NSObject 類在 oc 中的定義是:

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}
typedef struct objc_class *Class;
struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

舉個例子:

NSString *str = @"abc";

看下面的圖的定義圣勒,在這個例子中,str 的 isa 指針是指向 NSString摧扇,而 NSString 也有個 isa 指針圣贸,這個指針指向的類就是 元類,說明 NSString 是該元類的一個實例對象扳剿。NSString 的類方法就是在元類里定義的旁趟。


NSProxy 簡單用法:http://ios.jobbole.com/87856/
NSProxy 的作用:負(fù)責(zé)將消息轉(zhuǎn)發(fā)到真正的target的代理類。舉個例子庇绽,你想要賣一件二手物品锡搜,但是你并不想直接跟賣家接觸(直接向target發(fā)消息),這時你去找了一個第三方瞧掺,你告訴這個第三方你要買什么耕餐、出多少錢買、什么時候要等(向代理發(fā)消息)辟狈,第三方再去跟賣家接觸并把這些信息轉(zhuǎn)告賣家(轉(zhuǎn)發(fā)消息給真實的target)肠缔,最后通過第三方去完成這個交易夏跷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市明未,隨后出現(xiàn)的幾起案子槽华,更是在濱河造成了極大的恐慌,老刑警劉巖趟妥,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猫态,死亡現(xiàn)場離奇詭異,居然都是意外死亡披摄,警方通過查閱死者的電腦和手機(jī)亲雪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疚膊,“玉大人义辕,你說我怎么就攤上這事≡⒌粒” “怎么了灌砖?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贞让。 經(jīng)常有香客問我周崭,道長,這世上最難降的妖魔是什么喳张? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任续镇,我火速辦了婚禮,結(jié)果婚禮上销部,老公的妹妹穿的比我還像新娘摸航。我一直安慰自己,他們只是感情好舅桩,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布酱虎。 她就那樣靜靜地躺著,像睡著了一般擂涛。 火紅的嫁衣襯著肌膚如雪读串。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天撒妈,我揣著相機(jī)與錄音恢暖,去河邊找鬼。 笑死狰右,一個胖子當(dāng)著我的面吹牛杰捂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棋蚌,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼嫁佳,長吁一口氣:“原來是場噩夢啊……” “哼挨队!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蒿往,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤盛垦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后熄浓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體情臭,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年赌蔑,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竟秫。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡娃惯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出肥败,到底是詐尸還是另有隱情趾浅,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布馒稍,位于F島的核電站皿哨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏纽谒。R本人自食惡果不足惜证膨,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鼓黔。 院中可真熱鬧央勒,春花似錦、人聲如沸澳化。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裹驰。三九已至废麻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間列林,已是汗流浹背瑞你。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留席纽,地道東北人捏悬。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像润梯,于是被迫代替她去往敵國和親过牙。 傳聞我的和親對象是個殘疾皇子甥厦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

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

  • Objective-C作為面向?qū)ο缶幊躺ǔ皩ο蟆保╫bject)就是“基本構(gòu)造單元”(building block...
    Mark_Lin閱讀 325評論 0 1
  • 6.理解“屬性”這一概念 @dynamic關(guān)鍵字:告訴編譯器不要自動創(chuàng)建實現(xiàn)屬性所用的實例變量,也不要為其創(chuàng)建存取...
    Code_Ninja閱讀 709評論 0 3
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉缘挑,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,690評論 0 9
  • 三月陽光暖人身集歇, 林蔭喜鵲喳喳鳴。 桃花漸隨夜雨去语淘, 綠葉枝頭笑春風(fēng)诲宇。
    天馬酒仙閱讀 366評論 0 0
  • My code: My test result: 這道題目還是和前面的差不多。然后就是要用while循環(huán)把重復(fù)的數(shù)...
    Richardo92閱讀 238評論 0 1