1、 分類和類擴展區別
1. 分類實現原理
- Category編譯以後的底層結構是struct category_t,裏面存儲着分類的對象方法、類方法、屬性、協議信息
- 在程序運行的時候,runtime會將Category的數據,合併到類信息中(類對象、元類對象中)
2. Category和Class Extension的區別是什麼?
- Class Extension在編譯的時候,它的數據就已經包含在類信息中
- Category是在運行時,纔會將數據合併到類信息中
2、 分類爲啥不能添加成員變量
先看Category的底層結構面試
struct _category_t { const char *name; struct _class_t *cls; const struct _method_list_t *instance_methods; // 對象方法列表 const struct _method_list_t *class_methods; // 類方法列表 const struct _protocol_list_t *protocols; // 協議列表 const struct _prop_list_t *properties; // 屬性列表 };
1.從結構體能夠知道,有
屬性列表
,因此分類能夠聲明屬性
,可是分類只會生成該屬性對應的get
和set
的聲明
,沒有去實現該方法
。 2.結構體沒有成員變量列表
,因此不能聲明成員變量。數組
1. Category的加載處理過程
- 1.經過Runtime加載某個類的全部Category數據
- 2.把全部Category的方法、屬性、協議數據,合併到一個大數組中,後面參與編譯的Category數據,會在數組的前面
- 3.將合併後的分類數據(方法、屬性、協議),插入到類原來數據的前面
3、關聯對象給分類添加屬性
代碼實現以下code
- Student+Extern.m
#import "Student+Extern.h" #import <objc/runtime.h> static NSString *nameKey = @"nameKey"; //定義一個key值 @implementation Student (Extern) - (void)setName:(NSString *)name { objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY); } - (NSString *)name { return objc_getAssociatedObject(self, &nameKey); } @end
外界調用對象
Student *stu = [[Student alloc] init]; stu.name = @"喬碧蘿"; NSLog(@"name = %@",stu.name);
運行結果 - 關聯成功ci
可是注意,以上代碼僅僅是手動實現了setter/getter方法,但調用_成員變量依然報錯。get
更多:iOS面試題合集it