iOS高級軟件工程師面試題-基礎部分一、分類和擴展

分類和擴展有什麼區別?可以分別用來做什麼?分類有哪些侷限性?分類的結構體裡面有哪些成員?

答:1.1 分類(Category)

@interface 待擴展的類(分類的名稱)
@end
@implementation 待擴展的名稱(分類的名稱)
@end

OC中的特有語法,它是表示一個指向分類的結構體的指針。原則上它只能增加方法,不能增加成員(實例)變量。具體原因看源碼組成:

typedef struct objc_category *Category;
struct objc_category {
 char *category_name OBJC2_UNAVAILABLE; // 分類名
 char *class_name OBJC2_UNAVAILABLE; // 分類所屬的類名
 struct objc_method_list *instance_methods OBJC2_UNAVAILABLE; // 實例方法列表
 struct objc_method_list *class_methods OBJC2_UNAVAILABLE; // 類方法列表
 struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 分類所實現的協議列表
}

我們可以用@property聲明屬性,編譯和運行都會通過,只要不使用程序也不會崩潰。但如果調用了_成員變量和setter/getter方法,報錯就在所難免了。

如果分類中有和原有類 同名的方法, 會優先調用分類中的方法,會忽略原有類的方法。

同名方法調用的優先級為 分類 > 本類 > 父類。因此在開發中儘量不要覆蓋原有類。

如果多個分類中都有和原有類中同名的方法, 編譯器會執行最後一個參與編譯的分類中的方法。

1.2 類擴展(Class Extension)

Extension是Category的一個特例。類擴展與分類相比只少了分類的名稱,()裡面不用定義名稱,所以稱之為“匿名分類”。我們在.m文件中天天在用的。

@interface XXX ()
//私有屬性
//私有方法(如果不實現,編譯時會報警,Method definition for 'XXX' not found)
@end

為一個類添加額外的原來沒有變量,方法和屬性

一般的類擴展寫到.m文件中

一般的私有屬性寫到.m文件中的類擴展中

2、類別與類擴展的區別:

①類別中原則上只能增加方法(能添加屬性的的原因只是通過runtime解決無setter/getter的問題而已);

②類擴展不僅可以增加方法,還可以增加實例變量(或者屬性),只是該實例變量默認是@private類型的(範圍只能在自身類,而不是子類或其他地方);

③類擴展中聲明的方法沒被實現,編譯器會報警,但是類別中的方法沒被實現編譯器是不會有任何警告的。這是因為類擴展是在編譯階段被添加到類中,而類別是在運行時添加到類中。

④類擴展不能像類別那樣擁有獨立的實現部分(@implementation部分),也就是說,類擴展所聲明的方法必須依託對應類的實現部分來實現。

⑤定義在 .m 文件中的類擴展方法為私有的,定義在 .h 文件(頭文件)中的類擴展方法為公有的。類擴展是在 .m 文件中聲明私有方法的非常好的方式。

iOS高級軟件工程師面試題-基礎部分一、分類和擴展


分享到:


相關文章: