iOS面試題:分類和類擴展區別,爲啥分類不能添加成員變量,如何給分類添加屬性

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.從結構體能夠知道,有屬性列表,因此分類能夠聲明屬性,可是分類只會生成該屬性對應的getset聲明,沒有去實現該方法。 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

相關文章
相關標籤/搜索