Как я могу вызвать performSelectorOnMainThread: с селектором, который принимает> 1 аргумент?
Типичный вызов performSelectorOnMainThread:
выглядит следующим образом:
[target performSelectorOnMainThread:action withObject:foo waitUntilDone:NO];
где "result" - это аргумент, переданный "action". Соответствующим действием будет:
- (void)doSomethingWithThing1:(id *)thing1
Каков правильный синтаксис для вызова действия, которое принимает > 1 аргумент? Например:
- (void)doSomethingWithThing1:(id *)thing1 andThing2(id *)thing2 andAlsoThing3(id *)thing3
[target performSelectorOnMainThread:action withObject:??? waitUntilDone:NO];
Ответы
Ответ 1
В ответ на аналогичный вопрос о передаче не-объектов методу в performSelectorOnMainThread:
я указал на Dave Dribin категория в NSObject, которая позволяет вам сделать что-то вроде следующего:
[[person dd_invokeOnMainThread] doSomethingWithThing1:thing1 andThing2:thing2 andAlsoThing3:thing3];
для выполнения вашего метода с несколькими аргументами в основном потоке. Я думаю, что это довольно элегантное решение. За кулисами он обертывает вещи в NSInvocation, вызывая это в основном потоке.
Янтарная структура также делает что-то похожее.
Ответ 2
Вы можете сделать это, поместив ваши аргументы в словарь или массив и передав их специальной функции
- (void)doStuff:(NSString *)arg1 and:(NSString *)arg2 and:(NSString *)arg3 {
...
}
- (void)doStuff:(NSArray *)argArray {
[self doStuff:[argArray objectAtIndex:0]
and:[argArray objectAtIndex:1]
and:[argArray objectAtIndex:2];
}
Ответ 3
Если вы хотите сохранить подпись метода получателя, я думаю, вам нужно будет использовать NSInvocation
, который позволяет указать несколько значений аргументов.
Вы можете обернуть свой вызов и использовать словарь в качестве контейнера для своих аргументов, как предложено в другом ответе, но для меня это похоже на запах кода.
Лучшим решением этой линии было бы создание класса, который инкапсулирует значения аргументов, т.е. строго типизированный подход. Так, например, вместо передачи firstname
, surname
вы должны передать экземпляр класса Person
. Вероятно, это лучший путь, потому что методы с меньшим количеством аргументов могут дать более чистый код, но что целая другая история.