Вызывающий селектор с двумя аргументами по проблеме NSThread

Я хочу сделать Thread с несколькими аргументами. Является ли это возможным? У меня есть функция:

-(void) loginWithUser:(NSString *) user password:(NSString *) password {
}

И я хочу назвать эту функцию селектором:

[NSThread detachNewThreadSelector:@selector(loginWithUser:user:password:) toTarget:self withObject:@"someusername" withObject:@"somepassword"]; // this is wrong


Как передать два аргумента с параметром object в этой функции detachNewThreadSelect?

Возможно ли это?

Ответы

Ответ 1

Вам нужно передать дополнительные параметры в объекте, переданном в withObject, так:

NSDictionary *extraParams = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"user",@"password",nil] andKeys:[NSArray arrayWithObjects:@"valueForUser",@"valueForPassword",nil]]

[NSThread detachNewThreadSelector:@selector(loginWithUser:) toTarget:self withObject:extraParams]; 

Ответ 2

Это не работает, непроверено:

NSThread+ManyObjects.h:

@interface NSThread (ManyObjects)

+ (void)detachNewThreadSelector:(SEL)aSelector
                       toTarget:(id)aTarget 
                     withObject:(id)anArgument
                      andObject:(id)anotherArgument;

@end

NSThread+ManyObjects.m:

@implementation NSThread (ManyObjects)

+ (void)detachNewThreadSelector:(SEL)aSelector
                       toTarget:(id)aTarget 
                     withObject:(id)anArgument
                      andObject:(id)anotherArgument
{
    NSMethodSignature *signature = [aTarget methodSignatureForSelector:aSelector];
    if (!signature) return;

    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:aTarget];
    [invocation setSelector:aSelector];
    [invocation setArgument:&anArgument atIndex:2];
    [invocation setArgument:&anotherArgument atIndex:3];
    [invocation retainArguments];

    [self detachNewThreadSelector:@selector(invoke) toTarget:invocation withObject:nil];
}

@end

И затем вы можете импортировать NSThread+ManyObjects и вызвать

[NSThread detachNewThreadSelector:@selector(loginWithUser:user:password:) toTarget:self withObject:@"someusername" andObject:@"somepassword"];

Ответ 3

Оберните выбранный метод вспомогательным методом обтекания, wrappingMethod ", который обрабатывает NSArray входов в соответствии с вашим собственным методом перед вызовом вашего собственного метода в wrappingMethod. Теперь отделите NSThread, который выбирает все ваши новые wrappingMethod и берет экземпляр NSArray для withObject.

Кроме того: наличие обертки здесь может быть особенно полезно, если ваш исходный метод принимает один или несколько примитивных типов в качестве входных данных, и вам тогда придется работать с NSNumber или NSStrings, скажем, для удовлетворения NSThread.

Ответ 4

Обновление для хорошего ответа ennuikiller:

NSDictionary* params = [NSDictionary dictionaryWithObjectsAndKeys:@"IMG_URL_VALUE",@"img_url",@"PARAM2_VALUE", @"param2", nil];

[NSThread detachNewThreadSelector:@selector(loadImage:) toTarget:self withObject:params];