it-swarm.com.de

Wie kann ich @selector als Parameter übergeben?

Für die Methode:

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR];

Wie kann ich einen @selector übergeben? Ich habe versucht, es in (id) umzuwandeln, damit es kompiliert wird, aber es stürzt zur Laufzeit ab.


Genauer gesagt, ich habe eine Methode wie diese:

+(void)method1:(SEL)selector{
[NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector];   
}

Es stürzt ab. Wie übergebe ich den Selector, ohne abzustürzen, damit der neue Thread den Selector aufrufen kann, wenn der Thread fertig ist?

51
erotsppa

Das Problem hierbei besteht nicht darin, einen Selektor an eine Methode per se zu übergeben, sondern einen Selektor zu übergeben, an den ein Objekt erwartet wird. Um einen Nicht-Objektwert als Objekt zu übergeben, können Sie NSValue verwenden. In diesem Fall müssen Sie eine Methode erstellen, die einen NSValue akzeptiert und den entsprechenden Selektor abruft. Hier ist eine Beispielimplementierung:

@implementation Thing
- (void)method:(SEL)selector {
    // Do something
}

- (void)methodWithSelectorValue:(NSValue *)value {
    SEL selector;

    // Guard against buffer overflow
    if (strcmp([value objCType], @encode(SEL)) == 0) {
        [value getValue:&selector];
        [self method:selector];
    }
}

- (void)otherMethodShownInYourExample {
    SEL selector = @selector(something);
    NSValue *selectorAsValue = [NSValue valueWithBytes:&selector objCType:@encode(SEL)];
    [NSThread detachNewThreadSelector:@selector(methodWithSelectorValue:) toTarget:self withObject:selectorAsValue];
}
@end
67
Chuck

Sie können zwischen Selektoren und Zeichenfolgenobjekten mit den Funktionen NSStringFromSelector() und NSSelectorFromString() konvertieren. Sie können also stattdessen einfach String-Objekte übergeben.

Wenn Sie Ihre Methoden nicht ändern möchten, können Sie alternativ eine NSInvocation erstellen, um einen Aufruf für Ihren Methodenaufruf zu erstellen (da er Aufrufe mit Nicht-Objekt-Argumenten einrichten kann). Anschließend rufen Sie ihn mit [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil]; auf.

42
user102008

Verwenden Sie NSValue wie folgt:

+(void)method1:(SEL)selector {
    NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)];
    [NSThread detachNewThreadSelector:@selector(method2:) 
                             toTarget:self 
                           withObject:selectorValue];
}

NSValue ist als Object-Wrapper für beliebige Nicht-Objekttypen gedacht.

4
BJ Homer
2
ennuikiller

Wenn Sie kein Objekt angeben möchten, verwenden Sie einfach nil.

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:nil];

Wenn Sie ein Objekt an den Selektor übergeben müssen, würde es ungefähr so ​​aussehen.

Hier übergebe ich einen String an die Methode "setText".

NSString *string = @"hello world!";
 [NSThread detachNewThreadSelector:@selector(setText:) toTarget:self withObject:string];


-(void)setText:(NSString *)string {
    [UITextField setText:string]; 
}
0