91

私は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

私が欠けているものに関するアイデアはありますか?

4

10 に答える 10

97

メソッドのようなものは存在しないから[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];
于 2011-12-08T23:14:39.107 に答える
34

パラメータを 1 つのオブジェクトにパッケージ化し、ヘルパー メソッドを使用して元のメソッドを呼び出すことができます。

もう 1 つのオプションは 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:

于 2011-12-08T23:25:08.957 に答える
7

NSArray最も簡単なオプションは、またはなどの両方の引数を含む単一のパラメーターを取るようにメソッドを変更することですNSDictionary(または、単一のパラメーターを受け取り、それをアンパックし、最初のメソッドを呼び出し、次に 2 番目のメソッドを呼び出す 2 番目のメソッドを追加します。遅れ)。

たとえば、次のようなものがあります。

- (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];
于 2011-12-08T23:23:37.447 に答える
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];
于 2011-12-08T23:21:27.260 に答える
5

提供されている performSelector: メソッドのすべてのタイプは、次の場所にあります。

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: 
于 2011-12-08T23:24:18.003 に答える
1

いくつかのスウィズリングを行ったところ、元のメソッドを呼び出す必要がありました。私がしたことは、プロトコルを作成し、オブジェクトをそれにキャストすることでした。もう 1 つの方法は、カテゴリでメソッドを定義することですが、警告を抑制する必要があります (#pragma clang diagnostic ignored "-Wincomplete-implementation")。

于 2013-03-27T09:41:26.643 に答える
0

シンプルで再利用可能な方法は、拡張NSObjectして実装することです

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

何かのようなもの:

- (void)performSelector:(SEL)aSelector withObjects:(NSArray *)arguments
{
    NSMethodSignature *signature = [self methodSignatureForSelector: aSelector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature];
    [invocation setSelector: aSelector];

    int index = 2; //0 and 1 reserved
    for (NSObject *argument in arguments) {
        [invocation setArgument: &argument atIndex: index];
        index ++;
    }
    [invocation invokeWithTarget: self];
}
于 2019-05-02T14:51:52.930 に答える