iOS - 如何使用多个参数和afterDelay实现performSelector?

时间:2011-12-08 23:11:23

标签: iphone ios selector performselector

我是iOS新手。我有一个选择器方法如下 -

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second
{

}

我正在尝试实现类似的东西 -

[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second" afterDelay:15.0];

但这给我一个错误说 -

Instance method -performSelector:withObject:withObject:afterDelay: not found

关于我缺少什么的任何想法?

10 个答案:

答案 0 :(得分:140)

就个人而言,我认为更接近您的需求的解决方案是使用NSInvocation。

以下内容将完成工作:

indexPath dataSource 是在同一方法中定义的两个实例变量。

SEL aSelector = NSSelectorFromString(@"dropDownSelectedRow:withDataSource:");

if([dropDownDelegate respondsToSelector:aSelector]) {
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[dropDownDelegate methodSignatureForSelector:aSelector]];
    [inv setSelector:aSelector];
    [inv setTarget:dropDownDelegate];

    [inv setArgument:&(indexPath) atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
    [inv setArgument:&(dataSource) atIndex:3]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation

    [inv invoke];
}

答案 1 :(得分:98)

因为没有[NSObject performSelector:withObject:withObject:afterDelay:]方法。

您需要将要发送的数据封装到单个Objective C对象(例如NSArray,NSDictionary,某些自定义Objective C类型)中,然后通过众所周知的[NSObject performSelector:withObject:afterDelay:]方法传递它和爱。

例如:

NSArray * arrayOfThingsIWantToPassAlong = 
    [NSArray arrayWithObjects: @"first", @"second", nil];

[self performSelector:@selector(fooFirstInput:) 
           withObject:arrayOfThingsIWantToPassAlong  
           afterDelay:15.0];

答案 2 :(得分:34)

您可以将参数打包到一个对象中,并使用辅助方法将原始方法称为Michael,其他人现在已经建议。

另一个选项是dispatch_after,它将占用一个块并在某个时间将其排队。

double delayInSeconds = 15.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);

dispatch_after(popTime, dispatch_get_main_queue(), ^(void){

    [self fooFirstInput:first secondInput:second];

});

或者,正如您已经发现的那样,如果您不需要延迟,则只需使用- performSelector:withObject:withObject:

答案 3 :(得分:8)

最简单的选择是修改你的方法以获取包含两个参数的单个参数,例如NSArrayNSDictionary(或者添加第二个接受单个参数的方法,解压缩它,以及调用第一个方法,然后在延迟时调用第二个方法。

例如,您可以使用以下内容:

- (void) fooOneInput:(NSDictionary*) params {
    NSString* param1 = [params objectForKey:@"firstParam"];
    NSString* param2 = [params objectForKey:@"secondParam"];
    [self fooFirstInput:param1 secondInput:param2];
}

然后打电话给你,你可以这样做:

[self performSelector:@selector(fooOneInput:) 
      withObject:[NSDictionary dictionaryWithObjectsAndKeys: @"first", @"firstParam", @"second", @"secondParam", nil] 
      afterDelay:15.0];

答案 4 :(得分:6)

- (void) callFooWithArray: (NSArray *) inputArray
{
    [self fooFirstInput: [inputArray objectAtIndex:0] secondInput: [inputArray objectAtIndex:1]];
}


- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second
{

}

并将其命名为:

[self performSelector:@selector(callFooWithArray) withObject:[NSArray arrayWithObjects:@"first", @"second", nil] afterDelay:15.0];

答案 5 :(得分:5)

您可以在此处找到所有提供的performSelector:methods方法:

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsobject_Class/Reference/Reference.html

有许多变化但是没有一个版本可以接受多个对象以及延迟。你需要在NSArray或NSDictionary中包装你的参数。

- performSelector:
- performSelector:withObject:
- performSelector:withObject:withObject:
– performSelector:withObject:afterDelay:
– performSelector:withObject:afterDelay:inModes:
– performSelectorOnMainThread:withObject:waitUntilDone:
– performSelectorOnMainThread:withObject:waitUntilDone:modes:
– performSelector:onThread:withObject:waitUntilDone:
– performSelector:onThread:withObject:waitUntilDone:modes:
– performSelectorInBackground:withObject: 

答案 6 :(得分:2)

我不喜欢NSInvocation方式,太复杂了。让我们保持简单和干净:

// Assume we have these variables
id target, SEL aSelector, id parameter1, id parameter2;

// Get the method IMP, method is a function pointer here.
id (*method)(id, SEL, id, id) = (void *)[target methodForSelector:aSelector];

// IMP is just a C function, so we can call it directly.
id returnValue = method(target, aSelector, parameter1, parameter2);

答案 7 :(得分:1)

我只是做了一些调配,需要调用原始方法。我做的是制作协议并将我的对象投射到它。 另一种方法是在类别中定义方法,但需要抑制警告(#pragma clang diagnostic忽略“-Wincomplete-implementation”)。

答案 8 :(得分:0)

一种简单且可重用的方法是扩展<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools"> <TextView android:id="@+id/happy_birthday" android:text="@string/birthday" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp"/> <TextView android:id="@+id/dear_ian" android:layout_width="291dp" android:layout_height="wrap_content" android:layout_below="@id/happy_birthday" android:layout_marginStart="-127dp" android:layout_marginTop="3dp" android:layout_toEndOf="@id/happy_birthday" android:text="@string/ian" android:textSize="30sp" /> <ImageView android:src="@drawable/download" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" tools:ignore="ContentDescription"/> <TextView android:id="@+id/from_dennis" android:text="@string/dennis" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:textSize="30sp"/> 并实现

NSObject

类似:

- (void)performSelector:(SEL)aSelector withObjects:(NSArray *)arguments;

答案 9 :(得分:0)

我将创建一个自定义对象,将所有参数作为属性,然后将单个对象用作参数