objc主要类型和对象的可变参数

时间:2014-12-04 11:06:50

标签: ios nsinvocation variadic-functions

我有一套低层api,如下所示:

- (NSDictionary*) startRecord;
- (NSDictionary*) stopRecord;
- (NSDictionary*) switchMicrophone;
- (NSDictionary*) enableAutoRecord:(BOOL)enable;
- (NSDictionary*) deleteFile:(NSString*)filename;
- (NSDictionary*) enableDatetimeStampOverlay:(BOOL)enable;
- (NSDictionary*) setVideoResolution:(RESOLUTION_PARA)param;
- (NSDictionary*) setExposureValue:(EXPOSURE_VALUE_PARA)param;
- (NSDictionary*) setVolume:(VOLUME_PARA)param;
- (NSDictionary*) setWifiConfigWithSsid:(NSString*)ssid AndPassword:(NSString*)password;
- (NSDictionary*) formatSDCard;
// ... the # of parameters are at most 3

我想创建一个更高层的api来包装低层api,其中一个就像下面这样:

- (void) enableAutoRecord:(BOOL)isEnable
{
    ...
    dispatch_async( self.mySerialQueue, ^{
        ...
        NSDictionary *response = [self.lowerLayer enableAutoRecord:isEnable];
        ...
    });
}

对于更高层,我发现有这么多的复制和粘贴。我希望我可以改写如下:

- (void) enableAutoRecord:(BOOL)isEnable
{
     [self wrap_lower_layer_command:@"enableAutoRecord:", isEnable];
}

如何编写“wrap_lower_layer_command”?我研究过nsinvocation,objc_sendMsg和variadic参数。但我坚持类型问题。以调用为例:

T arg = p1;
[invocation setArgument:&arg atIndex:2];

我不知道p1的类型是什么。它可能是一个id,一个BOOL,一个int,或者其他东西。 有没有更好的方法来重构高层api中的复制和粘贴代码? 任何提示都表示赞赏!

1 个答案:

答案 0 :(得分:2)

您需要查看Message Forwarding

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    if ([self.lowerLayer respondsToSelector:[anInvocation selector]]) {
        [anInvocation retainArguments]; // Thanks newacct
        dispatch_async(self.mySerialQueue, ^{
            …
            [anInvocation invokeWithTarget:self.lowerLayer];

            void *returnValue;
            [invocation getReturnValue:&returnValue];
            NSDictionary *response = (__bridge NSDictionary *)returnValue;
            …
        });
    } else {
        [super forwardInvocation:anInvocation];
    }
}

我忘了包含关于返回值的部分。


添加了-retainArguments