標籤:命令設計模式
命令設計模式詳解
- 命令設計模式詳解
- 基本概念
- NSInvocation的使用
- 命令模式的體現
基本概念
命令設計模式將一個請求或行動作封裝為對象。這個封裝請求比原始的請求要靈活並且可以在對象之前被傳遞,儲存,動態修改或者放進隊列裡面。蘋果公司實現這種模式使用Target-Action機制和Invocation。
NSInvocation的使用
在 iOS中可以直接調用 某個對象的訊息 方式有2種
一種是performSelector:withObject:再一種就是NSInvocation第一種方式比較簡單,能完成簡單的調用。但是對於>2個的參數或者有傳回值的處理,那就需要做些額外工作才能搞定。那麼在這種情況下,我們就可以使用NSInvocation來進行這些相對複雜的操作
NSInvocation可以處理參數、傳回值。會java的人都知道反射操作,其實NSInvocation就相當於反射操作。
int main (int argc, const char * argv[]){ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; MyClass *myClass = [[MyClass alloc] init]; NSString *myString = @"My string"; //普通調用 NSString *normalInvokeString = [myClass appendMyString:myString]; NSLog(@"The normal invoke string is: %@", normalInvokeString); //NSInvocation調用 SEL mySelector = @selector(appendMyString:); NSMethodSignature * sig = [[myClass class] instanceMethodSignatureForSelector: mySelector]; NSInvocation * myInvocation = [NSInvocation invocationWithMethodSignature: sig]; [myInvocation setTarget: myClass]; [myInvocation setSelector: mySelector]; [myInvocation setArgument: &myString atIndex: 2]; NSString * result = nil; [myInvocation retainArguments]; [myInvocation invoke]; [myInvocation getReturnValue: &result]; NSLog(@"The NSInvocation invoke string is: %@", result); [myClass release]; [pool drain]; return 0;}MyClass.h#import <Foundation/Foundation.h>@interface MyClass : NSObject { }- (NSString *)appendMyString:(NSString *)string;@endMyClass.m#import "MyClass.h"@implementation MyClass- (id)init{ self = [super init]; if (self) { // Initialization code here. } return self;}- (NSString *)appendMyString:(NSString *)string{ NSString *mString = [NSString stringWithFormat:@"%@ after append method", string]; return mString;}- (void)dealloc{ [super dealloc];}@end
這裡說明一下[myInvocation setArgument: &myString atIndex: 2];為什麼index從2開始 ,原因為:0 1 兩個參數已經被target 和selector佔用。
命令模式的體現
NSMethodSignature *sig = [self methodSignatureForSelector:@selector(addAlbum:atIndex:)]; NSInvocation *undoAction = [NSInvocationinvocationWithMethodSignature:sig]; [undoAction setTarget:self]; [undoAction setSelector:@selector(addAlbum:atIndex:)]; [undoAction setArgument:&deletedAlbum atIndex:2]; [undoAction setArgument:¤tAlbumIndex atIndex:3]; [undoAction retainArguments]; [undoStack addObject:undoAction]; - (void)undoAction { if (undoStack.count > 0) { NSInvocation *undoAction = [undoStack lastObject]; [undoStack removeLastObject]; [undoAction invoke]; } }撤銷操作彈出棧頂的NSInvocation對象,然後通過invoke調用它
iOS常用設計模式——命令設計模式