iOS常用设计模式——命令设计模式

本文详细介绍了命令设计模式的基本概念及应用,并通过实例演示了如何使用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;
@end
MyClass.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:&currentAlbumIndex atIndex:3];   

    [undoAction retainArguments];   
    [undoStack addObject:undoAction];  

 - (void)undoAction   
{  
    if (undoStack.count > 0)   
    {   
        NSInvocation *undoAction = [undoStack lastObject];   
        [undoStack removeLastObject];   
        [undoAction invoke];   
    }    
}
撤销操作弹出栈顶的NSInvocation对象,然后通过invoke调用它
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值