Как мне вызвать executeSelectorOnMainThread: с селектором, который принимает> 1 аргумента? - PullRequest
14 голосов
/ 22 сентября 2009

Типичный вызов 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];

Ответы [ 3 ]

15 голосов
/ 22 сентября 2009

Вы можете сделать это, поместив свои аргументы в словарь или массив и передав их специальной функции

- (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];
}
8 голосов
/ 22 сентября 2009

В ответ на подобный вопрос о передаче не-объектов методу в performSelectorOnMainThread:, я указал на категорию Дэйва Дрибина для NSObject , которая позволяет вам делать что-то вроде следующее:

[[person dd_invokeOnMainThread] doSomethingWithThing1:thing1 andThing2:thing2 andAlsoThing3:thing3];

для выполнения вашего метода с несколькими аргументами в главном потоке. Я думаю, что это довольно элегантное решение. За кулисами он оборачивает вещи в NSInvocation, вызывая это в главном потоке.

Рамка Amber также делает нечто подобное.

1 голос
/ 22 сентября 2009

Если вы хотите сохранить сигнатуру метода получателя, то, я думаю, вам нужно взглянуть на использование NSInvocation, которое позволяет указывать несколько значений аргумента.

Вы могли бы обернуть свой вызов и использовать словарь в качестве контейнера для своих аргументов, как предложено в другом ответе, но мне это кажется немного запахом кода.

Лучшим решением в этом направлении было бы создание класса, который инкапсулирует значения аргументов, то есть строго типизированный подход. Так, например, вместо передачи firstname, surname, вы должны передать экземпляр класса Person. Вероятно, это лучший путь, чтобы пойти дальше, потому что методы с меньшим количеством аргументов могут привести к более чистому коду, но это совсем другая история .

...