Pour la méthode:
[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR];
Comment passer dans un @selector? J'ai essayé de le convertir en (id) pour le compiler, mais il se bloque au moment de l'exécution.
Plus spécifiquement, j'ai une méthode comme celle-ci:
+(void)method1:(SEL)selector{
[NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector];
}
Ça plante. Comment passer dans le sélecteur sans se planter, afin que le nouveau thread puisse appeler le sélecteur lorsque le thread est prêt?
Le problème ici n'est pas de passer un sélecteur à une méthode, mais de passer à un sélecteur lorsqu'un objet est attendu. Pour transmettre une valeur non-objet en tant qu'objet, vous pouvez utiliser NSValue
. Dans ce cas, vous devez créer une méthode qui accepte une NSValue et récupère le sélecteur approprié. Voici un exemple d'implémentation:
@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
Vous pouvez convertir des sélecteurs et des objets chaîne à l'aide des fonctions NSStringFromSelector()
et NSSelectorFromString()
. Vous pouvez donc simplement passer des objets chaîne à la place.
Sinon, si vous ne souhaitez pas modifier vos méthodes, vous pouvez créer un NSInvocation
pour créer un appel pour votre appel de méthode (puisqu'il peut configurer des invocations avec des arguments non-objet), puis l'appelez do [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];
Utilisez NSValue, comme suit:
+(void)method1:(SEL)selector {
NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)];
[NSThread detachNewThreadSelector:@selector(method2:)
toTarget:self
withObject:selectorValue];
}
NSValue est conçu comme encapsuleur d’objets pour les types non-objets arbitraires.
Veuillez voir: passer une méthode en argument
Si vous ne voulez pas spécifier d'objet, utilisez nil.
[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:nil];
Si vous devez passer un objet au sélecteur, cela ressemblerait à quelque chose comme ça.
Ici, je passe une chaîne à la méthode "setText".
NSString *string = @"hello world!";
[NSThread detachNewThreadSelector:@selector(setText:) toTarget:self withObject:string];
-(void)setText:(NSString *)string {
[UITextField setText:string];
}