iOS知識基礎篇

category 和 extension 的區(qū)別

  • 分類有名字桨醋,類擴展沒有分類名字重荠,是一種特殊的分類
  • 分類只能擴展方法(屬性僅僅是聲明氯葬,并沒真正實現(xiàn))晌端,類擴展可以擴展屬性捅暴、成員變量和方法

define 和 const常量有什么區(qū)別?

  • define在預處理階段進行替換,const常量在編譯階段使用
  • 宏不做類型檢查咧纠,僅僅進行替換伶唯,const常量有數(shù)據(jù)類型,會執(zhí)行類型檢查
  • define不能調試惧盹,const常量可以調試
  • define可以定義一些簡單的函數(shù)乳幸,const不可以

__block和__weak修飾符的區(qū)別?

  • __block不管是ARC還是MRC模式下可以使用钧椰,可以修飾對象粹断,也可以修飾基本數(shù)據(jù)類型
  • __weak只能在ARC模式下使用,只能修飾對象(NSString)嫡霞,不能修飾基本數(shù)據(jù)類型
  • __block修飾的對象可以在block中被重新賦值瓶埋,__weak修飾的對象不可以

static關鍵字的作用

  • 函數(shù)(方法)體內 static 變量的作用范圍為該函數(shù)體,該變量的內存只被分配一次诊沪,因此其值在下次調用時仍維持上次的值养筒;
  • 在模塊內的 static 全局變量可以被模塊內所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問端姚;
  • 在模塊內的 static 函數(shù)只可被這一模塊內的其它函數(shù)調用晕粪,這個函數(shù)的使用范圍被限制在聲明 它的模塊內;
  • 在類中的 static 成員變量屬于整個類所擁有渐裸,對類的所有對象只有一份拷貝巫湘;
  • 在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針昏鹃,因而只能訪問類的static 成員變量

堆和棧的區(qū)別

  • 從管理方式來講
    • 對于棧來講尚氛,是由編譯器自動管理,無需我們手工控制洞渤;
    • 對于堆來說阅嘶,釋放工作由程序員控制,容易產生內存泄露(memory leak)
  • 從申請大小大小方面講
    • 椩仄空間比較小
    • 堆控件比較大
  • 從數(shù)據(jù)存儲方面來講
    • 椦度幔空間中一般存儲基本類型,對象的地址
    • 堆空間一般存放對象本身宪巨,block的copy等

風格糾錯題

  • 修改后的代碼
typedef NS_ENUM(NSInteger, CYLSex)
{
  CYLSexMan,
  CYLSexWoman
};

@interface CYLUser : NSObject<NSCopying>

@property (nonatomic, copy, readonly) NSString *name;
@property (nonatomic, assign, readonly) NSUInteger age;
@property (nonatomic, assign, readwrite) CYLSex sex;

- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;
- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age;
+ (instancetype)userWithName:(NSString *)name age:(NSUInteger)age sex:(CYLSex)sex;

@end

Objective-C使用什么機制管理對象內存?

  • MRC 手動引用計數(shù)
  • ARC 自動引用計數(shù),現(xiàn)在通常ARC
  • 通過 retainCount 的機制來決定對象是否需要釋放捏卓。 每次 runloop 的時候极祸,都會檢查對象的 retainCount慈格,如果retainCount 為 0,說明該對象沒有地方需要繼續(xù)使用了遥金,可以釋放掉了

ARC通過什么方式幫助開發(fā)者管理內存浴捆?

  • 通過編譯器在編譯的時候,插入類似內存管理的代碼

ARC是為了解決什么問題誕生的?

  • 首先解釋ARC: automatic reference counting自動引用計數(shù)
  • 了解MRC的缺點
    • 在MRC時代當我們要釋放一個堆內存時稿械,首先要確定指向這個堆空間的指針都被release了
    • 釋放指針指向的堆空間选泻,首先要確定哪些指針指向同一個堆,這些指針只能釋放一次(MRC下即誰創(chuàng)建美莫,誰釋放页眯,避免重復釋放)
    • 模塊化操作時,對象可能被多個模塊創(chuàng)建和使用厢呵,不能確定最后由誰去釋放
    • 多線程操作時窝撵,不確定哪個線程最后使用完畢
  • 綜上所述,MRC有諸多缺點襟铭,很容易造成內存泄露和壞內存的問題碌奉,這時蘋果為盡量解決這個問題,從而誕生了ARC

ARC下還會存在內存泄露嗎寒砖?

  • 循環(huán)引用會導致內存泄露
  • Objective-C對象與CoreFoundation對象進行橋接的時候如果管理不當也會造成內存泄露
  • CoreFoundation中的對象不受ARC管理赐劣,需要開發(fā)者手動釋放

什么情況使用weak關鍵字,相比assign有什么不同哩都?

  • 首先明白什么情況使用weak關鍵字魁兼?
    • 在ARC中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用weak來解決,比如:delegate代理屬性,代理屬性也可使用assign
    • 自身已經對它進行一次強引用,沒有必要再強引用一次,此時也會使用weak,自定義IBOutlet控件屬性一般也使用weak茅逮;當然璃赡,也可以使用strong判哥,但是建議使用weak
  • weak 和 assign的不同點
    • weak策略在屬性所指的對象遭到摧毀時献雅,系統(tǒng)會將weak修飾的屬性對象的指針指向nil,在OC給nil發(fā)消息是不會有什么問題的塌计;如果使用assign策略在屬性所指的對象遭到摧毀時挺身,屬性對象指針還指向原來的對象氓鄙,由于對象已經被銷毀宁改,這時候就產生了野指針堰汉,如果這時候在給此對象發(fā)送消息蔬啡,很容造成程序奔潰
    • assigin 可以用于修飾非OC對象,而weak必須用于OC對象

@property 的本質是什么叙淌?

  • @property其實就是在編譯階段由編譯器自動幫我們生成ivar成員變量褂萧,getter方法荞雏,setter方法

ivar胎撤、getter伊脓、setter是如何生成并添加到這個類中的府寒?

  • 使用“自動合成”( autosynthesis)

  • 這個過程由編譯器在編譯階段執(zhí)行自動合成,所以編輯器里看不到這些“合成方法”(synthesized method)的源代碼

  • 除了生成getter、setter方法之外株搔,編譯器還要自動向類中添加成員變量(在屬性名前面加下劃線剖淀,以此作為實例變量的名字)

  • 為了搞清屬性是怎么實現(xiàn)的,反編譯相關的代碼,他大致生成了五個東西

    // 該屬性的“偏移量” (offset),這個偏移量是“硬編碼” (hardcode)纤房,表示該變量距離存放對象的內存區(qū)域的起始地址有多遠
    OBJC_IVAR_$類名$屬性名稱
    
    // 方法對應的實現(xiàn)函數(shù)
    setter與getter
    
    // 成員變量列表
    ivar_list
    
    // 方法列表
    method_list
    
    // 屬性列表
    prop_list
    
    • 每次增加一個屬性纵隔,系統(tǒng)都會在ivar_list中添加一個成員變量的描述
    • 在method_list中增加setter與getter方法的描述
    • 在prop_list中增加一個屬性的描述
    • 計算該屬性在對象中的偏移量
    • 然后給出setter與getter方法對應的實現(xiàn),在setter方法中從偏移量的位置開始賦值,在getter方法中從偏移量開始取值,為了能夠讀取正確字節(jié)數(shù),系統(tǒng)對象偏移量的指針類型進行了類型強轉

@protocol 和 category 中如何使用 @property

  • 在protocol中使用property只會生成setter和getter方法聲明,我們使用屬性的目的,是希望遵守我協(xié)議的對象能實現(xiàn)該屬性
  • category 使用 @property也是只會生成setter和getter方法聲明,如果我們真的需要給category增加屬性的實現(xiàn),需要借助于運行時的兩個函數(shù)
objc_setAssociatedObject
objc_getAssociatedObject

@property后面可以有哪些修飾符?

  • 原子性---nonatomic特質
    • 如果不寫默認情況為atomic(系統(tǒng)會自動加上同步鎖炮姨,影響性能)
    • 在iOS開發(fā)中盡量指定為nonatomic捌刮,這樣有助于提高程序的性能
  • 讀/寫權限---readwrite(讀寫)、readooly (只讀)
  • 內存管理語義---assign舒岸、strong糊啡、 weak、unsafe_unretained吁津、copy
  • 方法名---getter=<name>棚蓄、setter=<name>
@property (nonatomic, getter=isOn) BOOL on;

// setter=<name>這種不常用,也**不推薦**使用碍脏。故不在這里給出寫法
  • 不常用的:nonnull,null_resettable,nullable

使用atomic一定是線程安全的嗎梭依?

  • 不是,atomic的本意是指屬性的存取方法是線程安全的典尾,并不保證整個對象是線程安全的役拴。
  • 舉例:聲明一個NSMutableArray的原子屬性stuff,此時self.stuff 和self.stuff = othersulf都是線程安全的钾埂。但是河闰,使用[self.stuff objectAtIndex:index]就不是線程安全的,需要用互斥鎖來保證線程安全性

@synthesize 和 @dynamic分別有什么作用

  • @property有兩個對應的詞褥紫,一個是@synthesize姜性,一個是@dynamic。如果@synthesize和@dynamic都沒寫髓考,那么默認的就是@syntheszie var = _var;
  • @synthesize的語義是如果你沒有手動實現(xiàn)setter方法和getter方法部念,那么編譯器會自動為你加上這兩個方法
  • @dynamic告訴編譯器:屬性的setter與getter方法由用戶自己實現(xiàn),不自動生成(當然對于readonly的屬性只需提供getter即可)
    • 假如一個屬性被聲明為@dynamic var氨菇,然后你沒有提供@setter方法和@getter方法儡炼,編譯的時候沒問題,但是當程序運行到instance.var = someVar查蓉,由于缺setter方法會導致程序崩潰乌询;或者當運行到 someVar = instance.var時,由于缺getter方法同樣會導致崩潰豌研。編譯時沒問題妹田,運行時才執(zhí)行相應的方法竣灌,這就是所謂的動態(tài)綁定

ARC下,不顯式指定任何屬性關鍵字時秆麸,默認的關鍵字都有哪些初嘹?

  • 基本數(shù)據(jù):atomic,readwrite,assign
  • 普通的OC對象:atomic,readwrite,strong

@synthesize合成實例變量的規(guī)則是什么?假如property名為foo沮趣,存在一個名為_foo的實例變量屯烦,那么還會自動合成新變量么?

  • 先回答第二個問題:不會

  • @synthesize合成成員變量的規(guī)則房铭,有以下幾點:

    • 如果指定了成員變量的名稱,會生成一個指定的名稱的成員變量
    • 如果這個成員已經存在了就不再生成了
    • 如果指定@synthesize foo;就會生成一個名稱為foo的成員變量驻龟,也就是說:會自動生成一個屬性同名的成員變量
    @interface XMGPerson : NSObject
    
    @property (nonatomic, assign) int age;
    
    @end
    
    @implementation XMGPerson
    
    // 不加這語句默認生成的成員變量名為_age
    // 如果加上這一句就會生成一個跟屬性名同名的成員變量
    @synthesize age;
    
    @end
    
    • 如果是 @synthesize foo = _foo; 就不會生成成員變量了

在有了自動合成屬性實例變量之后,@synthesize還有哪些使用場景缸匪?

  • 首先的搞清楚什么情況下不會autosynthesis(自動合成)
    • 同時重寫了setter和getter時
    • 重寫了只讀屬性的getter時
    • 使用了@dynamic時
    • 在 @protocol 中定義的所有屬性
    • 在 category 中定義的所有屬性
    • 重載的屬性翁狐,當你在子類中重載了父類中的屬性,必須 使用@synthesize來手動合成ivar
  • 應用場景
    • 當你同時重寫了setter和getter時凌蔬,系統(tǒng)就不會生成ivar)露懒。這時候有兩種選擇
      • 手動創(chuàng)建ivar
      • 使用@synthesize foo = _foo;,關聯(lián)@property與ivar
    • 可以用來修改成員變量名砂心,一般不建議這么做懈词,建議使用系統(tǒng)自動生成的成員變量

怎么用 copy 關鍵字?

  • NSString辩诞、NSArray坎弯、NSDictionary等等經常使用copy關鍵字,是因為他們有對應的可變類型:NSMutableString译暂、NSMutableArray抠忘、NSMutableDictionary,為確保對象中的屬性值不會無意間變動外永,應該在設置新屬性值時拷貝一份崎脉,保護其封裝性
  • block也經常使用copy關鍵字
    • block 使用 copy 是從 MRC 遺留下來的“傳統(tǒng)”,在 MRC 中,方法內部的 block 是在棧區(qū)的,使用 copy 可以把它放到堆區(qū).
    • 在ARC中寫不寫都行:對于 block 使用 copy 還是 strong 效果是一樣的,但是建議寫上copy象迎,因為這樣顯示告知調用者“編譯器會自動對 block 進行了 copy 操作”

用@property聲明的NSString(或NSArray荧嵌,NSDictionary)經常使用copy關鍵字,為什么砾淌?如果改用strong關鍵字,可能造成什么問題谭网?

  • 因為父類指針可以指向子類對象,使用copy的目的是為了讓本對象的屬性不受外界影響,使用copy無論給我傳入是一個可變對象還是不可對象,我本身持有的就是一個不可變的副本.
  • 如果我們使用是strong,那么這個屬性就有可能指向一個可變對象,如果這個可變對象在外部被修改了,那么會影響該屬性.

復制詳解

  • 淺復制(shallow copy):在淺復制操作時汪厨,對于被復制對象的每一層都是指針復制

  • 深復制(one-level-deep copy):在深復制操作時愉择,對于被復制對象劫乱,至少有一層是深復制织中。

  • 完全復制(real-deep copy):在完全復制操作時,對于被復制對象的每一層都是對象復制衷戈。

  • 非集合類對象的copy與mutableCopy

[不可變對象 copy] // 淺復制
[不可變對象 mutableCopy] //深復制
[可變對象 copy] //深復制
[可變對象 mutableCopy] //深復制
  • 集合類對象的copy與mutableCopy
[不可變對象 copy] // 淺復制
[不可變對象 mutableCopy] //單層深復制
[可變對象 copy] //單層深復制
[可變對象 mutableCopy] //單層深復制
  • 這里需要注意的是集合對象的內容復制僅限于對象本身狭吼,對象元素仍然是指針復制

這個寫法會出什么問題: @property (copy) NSMutableArray *array;

  • 因為copy策略拷貝出來的是一個不可變對象,然而卻把它當成可變對象使用殖妇,很容易造成程序崩潰
  • 這里還有一個問題刁笙,該屬性使用了同步鎖,會在創(chuàng)建時生成一些額外的代碼用于幫助編寫多線程程序谦趣,這會帶來性能問題疲吸,通過聲明nonatomic可以節(jié)省這些雖然很小但是不必要額外開銷,在iOS開發(fā)中應該使用nonatomic替代atomic

如何讓自定義類可以用 copy 修飾符前鹅?如何重寫帶 copy 關鍵字的 setter摘悴?

  • 若想令自己所寫的對象具有拷貝功能,則需實現(xiàn)NSCopying協(xié)議舰绘。如果自定義的對象分為可變版本與不可變版本蹂喻,那么就要同時實現(xiàn)NSCopyiog與NSMutableCopying協(xié)議,不過一般沒什么必要捂寿,實現(xiàn)NSCopying協(xié)議就夠了
// 實現(xiàn)不可變版本拷貝
- (id)copyWithZone:(NSZone *)zone;

// 實現(xiàn)可變版本拷貝
- (id)mutableCopyWithZone:(NSZone *)zone;

// 重寫帶 copy 關鍵字的 setter
- (void)setName:(NSString *)name
{
    _name = [name copy];
}

+(void)load; +(void)initialize;有什么用處叉橱?

  • +(void)load;
    • 當類對象被引入項目時, runtime 會向每一個類對象發(fā)送 load 消息
    • load 方法會在每一個類甚至分類被引入時僅調用一次,調用的順序:父類優(yōu)先于子類, 子類優(yōu)先于分類
    • 由于 load 方法會在類被import 時調用一次,而這時往往是改變類的行為的最佳時機,在這里可以使用例如method swizlling 來修改原有的方法
    • load 方法不會被類自動繼承
  • +(void)initialize;
    • 也是在第一次使用這個類的時候會調用這個方法者蠕,也就是說 initialize也是懶加載
  • 總結:
    • 在Objective-C中窃祝,runtime會自動調用每個類的這兩個方法
    • +load會在類初始加載時調用
    • +initialize會在第一次調用類的類方法或實例方法之前被調用
    • 這兩個方法是可選的,且只有在實現(xiàn)了它們時才會被調用
    • 兩者的共同點:兩個方法都只會被調用一次

Foundation對象與Core Foundation對象有什么區(qū)別

  • Foundation框架是使用OC實現(xiàn)的踱侣,Core Foundation是使用C實現(xiàn)的

  • Foundation對象 和 Core Foundation對象間的轉換:俗稱橋接

    • ARC環(huán)境橋接關鍵字:
    // 可用于Foundation對象 和 Core Foundation對象間的轉換
    __bridge
    
    // 用于Foundation對象 轉成 Core Foundation對象
    __bridge_retained
    
    // Core Foundation對象 轉成 Foundation對象
    __bridge_transfer
    
      - Foundation對象 轉成 Core Foundation對象
          - 使用`__bridge`橋接
              - 如果使用`__bridge`橋接,它`僅僅`是將strOC的`地址`給了strC, 并`沒有`轉移對象的所有權粪小,也就是說, 如果使用__bridge橋接, 那么如果strOC釋放了,strC也不能用了
              - 注意:在ARC條件下,如果是使用__bridge橋接,那么strC`可以不用主動釋放`, 因為ARC會自動管理strOC和strC
    
          ```objc
          NSString *strOC1 = [NSString stringWithFormat:@"abcdefg"];
          CFStringRef strC1 = (__bridge CFStringRef)strOC1;
       NSLog(@"%@ %@", strOC1, strC1);
          ```
    
          - 使用`__bridge_retained`橋接
              - 如果使用__bridge_retained橋接,它會將對象的`所有權轉移`給strC, 也就是說, `即便strOC被釋放了, strC也可以使用`
              - 注意:在ARC條件下,如果是使用__bridge_retained橋接,那么strC`必須自己手動釋放`,因為橋接的時候已經將對象的所有權轉移給了strC,而C語言的東西不是不歸ARC管理的
    
          ```objc
          NSString *strOC2 = [NSString stringWithFormat:@"abcdefg"];
          //    CFStringRef strC2 = (__bridge_retained CFStringRef)strOC2;
          CFStringRef strC2 = CFBridgingRetain(strOC2);// 這一句, 就等同于上一句
          CFRelease(strC2);
          ```
      - Core Foundation對象 轉成 Foundation對象
          - 使用__bridge橋接
              - 如果使用__bridge橋接,它`僅僅`是將strC的`地址`給了strOC, 并`沒有`轉移對象的所有權
              - 也就是說如果使用__bridge橋接,那么如果strC釋放了,strOC也不能用了
    
          ```objc
          CFStringRef strC3 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
          NSString *strOC3 = (__bridge NSString *)strC3;
          CFRelease(strC3);
          ```
    
          - 使用__bridge_transfer橋接
              - 如果使用__bridge_transfer橋接,它會將對象的`所有權轉移`給strOC, 也就是說, `即便strC被釋放了, strOC也可以使用`
              - 如果使用__bridge_transfer橋接, 他會自動釋放strC, 也就是以后我們`不用手動釋放strC`
    
          ```objc
          CFStringRef strC4 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
          //     NSString *strOC = (__bridge_transfer NSString *)strC;
          NSString *strOC4 = CFBridgingRelease(strC4); // 這一句, 就等同于上一句
          ```
    
    • MRC環(huán)境:直接強轉
    -(void)bridgeInMRC
    {
        // 將Foundation對象轉換為Core Foundation對象,直接強制類型轉換即可
        NSString *strOC1 = [NSString stringWithFormat:@"xxxxxx"];
        CFStringRef strC1 = (CFStringRef)strOC1;
        NSLog(@"%@ %@", strOC1, strC1);
        [strOC1 release];
        CFRelease(strC1);
    
        // 將Core Foundation對象轉換為Foundation對象抡句,直接強制類型轉換即可
        CFStringRef strC2 = CFStringCreateWithCString(CFAllocatorGetDefault(), "12345678", kCFStringEncodingASCII);
        NSString *strOC2 = (NSString *)strC2;
        NSLog(@"%@ %@", strOC2, strC2);
        [strOC2 release];
        CFRelease(strC2);
    }
    

addObserver:forKeyPath:options:context:各個參數(shù)的作用分別是什么探膊,observer中需要實現(xiàn)哪個方法才能獲得KVO回調?

/**
 1. self.person:要監(jiān)聽的對象
 2. 參數(shù)說明
    1> 觀察者待榔,負責處理監(jiān)聽事件的對象
    2> 要監(jiān)聽的屬性
    3> 觀察的選項(觀察新逞壁、舊值,也可以都觀察)
    4> 上下文锐锣,用于傳遞數(shù)據(jù)腌闯,可以利用上下文區(qū)分不同的監(jiān)聽
 */
[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];

/**
 *  當監(jiān)控的某個屬性的值改變了就會調用
 *
 *  @param keyPath 監(jiān)聽的屬性名
 *  @param object  屬性所屬的對象
 *  @param change  屬性的修改情況(屬性原來的值、屬性最新的值)
 *  @param context 傳遞的上下文數(shù)據(jù)雕憔,與監(jiān)聽的時候傳遞的一致姿骏,可以利用上下文區(qū)分不同的監(jiān)聽
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@對象的%@屬性改變了:%@", object, keyPath, change);
}

KVO內部實現(xiàn)原理

  • KVO是基于runtime機制實現(xiàn)的
  • 當某個類的屬性對象第一次被觀察時,系統(tǒng)就會在運行期動態(tài)地創(chuàng)建該類的一個派生類斤彼,在這個派生類中重寫基類中任何被觀察屬性的setter 方法分瘦。派生類在被重寫的setter方法內實現(xiàn)真正的通知機制
  • 如果原類為Person蘸泻,那么生成的派生類名為NSKVONotifying_Person
  • 每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察嘲玫,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類悦施,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法
  • 鍵值觀察通知依賴于NSObject 的兩個方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個被觀察屬性發(fā)生改變之前去团, willChangeValueForKey: 一定會被調用抡诞,這就 會記錄舊的值。而當改變發(fā)生后渗勘,didChangeValueForKey: 會被調用沐绒,繼而 observeValueForKey:ofObject:change:context: 也會被調用。
  • 補充:KVO的這套實現(xiàn)機制中蘋果還偷偷重寫了class方法旺坠,讓我們誤認為還是使用的當前類乔遮,從而達到隱藏生成的派生類

如何手動觸發(fā)一個value的KVO

  • 自動觸發(fā)的場景:在注冊KVO之前設置一個初始值,注冊之后取刃,設置一個不一樣的值蹋肮,就可以觸發(fā)了
  • 想知道如何手動觸發(fā),必須知道自動觸發(fā) KVO 的原理璧疗,見上面的描述
  • 手動觸發(fā)演示
@property (nonatomic, strong) NSDate *now;

- (void)viewDidLoad
{
    [super viewDidLoad];

    // “手動觸發(fā)self.now的KVO”坯辩,必寫。
    [self willChangeValueForKey:@"now"];

    // “手動觸發(fā)self.now的KVO”崩侠,必寫漆魔。
    [self didChangeValueForKey:@"now"];
}

若一個類有實例變量NSString *_foo,調用setValue:forKey:時却音,是以foo還是_foo作為key改抡?

  • 都可以

KVC的keyPath中的集合運算符如何使用?

  • 必須用在集合對象上或普通對象的集合屬性
  • 簡單集合運算符有@avg系瓢, @count 阿纤, @max , @min 夷陋,@sum
  • 格式 @"@sum.age" 或 @"集合屬性.@max.age"欠拾??骗绕?

KVC和KVO的keyPath一定是屬性么藐窄?

  • 可以是成員變量

如何關閉默認的KVO的默認實現(xiàn),并進入自定義的KVO實現(xiàn)爹谭?

apple用什么方式實現(xiàn)對一個對象的KVO枷邪?

  • 此題就是問KVO的實現(xiàn)原理
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市诺凡,隨后出現(xiàn)的幾起案子东揣,更是在濱河造成了極大的恐慌,老刑警劉巖腹泌,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘶卧,死亡現(xiàn)場離奇詭異,居然都是意外死亡凉袱,警方通過查閱死者的電腦和手機芥吟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來专甩,“玉大人钟鸵,你說我怎么就攤上這事〉佣悖” “怎么了棺耍?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長种樱。 經常有香客問我蒙袍,道長,這世上最難降的妖魔是什么嫩挤? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任害幅,我火速辦了婚禮,結果婚禮上岂昭,老公的妹妹穿的比我還像新娘以现。我一直安慰自己,他們只是感情好约啊,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布邑遏。 她就那樣靜靜地躺著,像睡著了一般棍苹。 火紅的嫁衣襯著肌膚如雪无宿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天枢里,我揣著相機與錄音孽鸡,去河邊找鬼。 笑死栏豺,一個胖子當著我的面吹牛彬碱,可吹牛的內容都是我干的。 我是一名探鬼主播奥洼,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼巷疼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了灵奖?” 一聲冷哼從身側響起嚼沿,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤估盘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后骡尽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遣妥,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年攀细,在試婚紗的時候發(fā)現(xiàn)自己被綠了箫踩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡谭贪,死狀恐怖境钟,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情俭识,我是刑警寧澤慨削,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站鱼的,受9級特大地震影響理盆,放射性物質發(fā)生泄漏。R本人自食惡果不足惜凑阶,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一猿规、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宙橱,春花似錦姨俩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宝冕,卻和暖如春张遭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背地梨。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工菊卷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宝剖。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓洁闰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親万细。 傳聞我的和親對象是個殘疾皇子扑眉,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容

  • category 和 extension 的區(qū)別? category :分類有名字,類擴展沒i有分類名字,是一種特...
    JonesCxy閱讀 297評論 0 1
  • category 和 extension 的區(qū)別? category :分類有名字腰素,類擴展沒i有分類名字聘裁,是一種特...
    WSGNSLog閱讀 182評論 0 1
  • 一、category 和 extension 的區(qū)別耸弄?(分類和擴展的區(qū)別) 1咧虎,分類有名字卓缰,類擴展沒有名字计呈,是一種...
    閃電迷閱讀 735評論 0 3
  • category 和 extension 的區(qū)別 -分類有名字,類擴展沒有分類名字征唬,是一種特殊的分類 -分類只能擴...
    白羊的羊閱讀 428評論 0 1
  • 這大半夜的 我他媽好想你捌显。 你來抱抱我好不好。 我一直都不喜歡他 我真的喜歡你 越來越濃 即使你和我什么都沒發(fā)生 ...
    草莓味的精靈閱讀 236評論 0 0