Posing,顧名思義,意思是「冒充」,它跟categories
類似,但本質上不一樣,Posing存在的目的在於子類可以冒充父類別,使得後續的程式碼無需把父類別修改為子類,就可以很方便的讓父類別表現成子類的行為,從而實現非常方便的冒充,這在一般的語言中是難以想象的。
在開始在Objective-C中進行構建之前,提醒讀者注意,在Mac OS X 10.5中宣告已經棄用了冒充(Posing),並且之後無法使用它。 因此對於那些不關心這些棄用方法的人可以跳過本章。
Objective-C允許類完全替換程式中的另一個類。替換類被稱為「冒充」目標類。 對於支援冒充的版本,傳送到目標類的所有訊息都由冒充類接收。
NSObject
包含poseAsClass
- 使我們能夠替換現有類的方法,如上所述。
它允許擴充套件一個類,並且全面的冒充這個超類,比如:有一個擴充套件NSArray
的NSArrayChild
物件,如果讓NSArrayChild
冒充NSArray
,則程式程式碼所在的NSArray
都會自動替換為NSArrayChild
。
注意,這裡不是指程式碼替換,而是NSArray
所在地方的行為都跟NSArrayChild
一樣了。
super
呼叫重寫的方法,從而結合目標類的實現。範例程式碼:
#import <Foundation/Foundation.h>
@interface MyString : NSString
@end
@implementation MyString
- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target
withString:(NSString *)replacement {
NSLog(@"The Target string is %@",target);
NSLog(@"The Replacement string is %@",replacement);
}
@end
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[MyString poseAsClass:[NSString class]];
NSString *string = @"Test";
[string stringByReplacingOccurrencesOfString:@"a" withString:@"c"];
[pool drain];
return 0;
}
執行上面範例程式碼,得到以下結果:
2018-11-22 21:23:44.729 Posing[372:306] The Target string is a
2018-11-22 21:23:44.730 Posing[372:306] The Replacement string is c
在上面的例子中,只是用實現汙染了原始方法,並且這將通過上述方法在所有NSString
操作中受到影響。