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
操作中受到影響。
上一篇:
Objective-C類別
下一篇:
Objective-C擴展