Objective-C: Как построить таблицу диспетчеризации команд?

Я создаю таблицу отправки команд в Objective-C, используя ARC. Хорошо ли выглядит форма, которую я использую ниже, или есть лучшая альтернатива?

Например:

    self.commandTable = [@{
                         @"command1" : ^(id value) { return [self runCommand1:value]; },
                         @"command2" : ^(id value) { return [self runCommand2:value]; },
                      } mutableCopy];
}

person Boon    schedule 20.02.2014    source источник
comment
Спасибо, отредактированный вопрос.   -  person Boon    schedule 21.02.2014


Ответы (1)


Я вижу как минимум две проблемы с вашим кодом.

Во-первых, блоки на основе стека (например, два, которые вы определяете в своем коде) не будут сохраняться автоматически, когда вы передаете их в коллекцию. Поэтому, скорее всего, когда вы захотите выполнить блок, ваше приложение рухнет. Это очень хорошо объяснено в ответе на вопрос, указанный @Josh в комментариях: Блок снимается в NSDictionary (ARC). Вы должны использовать метод копирования для блока, чтобы создать копию в куче, которую может сохранить ARC.

Во-вторых, после того, как вы вставили методы копирования, у вас будет цикл сохранения. Ваш объект "self" сохраняет словарь commandTable, словарь сохранит ваши блоки (это ваше намерение, вы не хотите, чтобы ваши блоки исчезли), и поскольку вы используете один и тот же объект "self" в блоках, ваши блоки сохранятся. ваш объект «я». Чтобы избежать этого, определите локальную переменную __weak для вашего объекта «я», как также описано в документе Работа с блоками глава документации:

MyClass* __weak weakSelf = self;
self.commandTable = [@{
                     @"command1" : ^(id value) { return [weakSelf runCommand1:value]; },
                     @"command2" : ^(id value) { return [weakSelf runCommand2:value]; },
                  } mutableCopy];

В противном случае ваш шаблон может работать хорошо.

person MrTJ    schedule 20.02.2014
comment
Согласно спецификации CLang, instancetype — это контекстное ключевое слово, которое разрешено только в типе результата метода Objective-C (источник: clang.llvm.org/docs/) Я не знаю, являются ли некоторые компиляторы более терпимыми в этом вопросе, позволяя вам использовать instancetype и в других местах, но Я бы не стал слишком полагаться на это. - person MrTJ; 21.02.2014
comment
Вы правы - похоже, что они изменили поведение ключевого слова с тех пор, как оно было впервые введено. Моя ошибка, эти вещи движутся так быстро. - person Richard J. Ross III; 21.02.2014
comment
@MrTJ Если указанный выше блок сохранен в свойство (неатомарное, копирование) id (^cmd) (значение id); я могу использовать self.cmd в словаре или мне все еще нужна [копия self.cmd]? - person Boon; 21.02.2014
comment
Свойство копирования сделает копию за вас, поэтому вам не нужно копировать его еще раз. Еще обратите внимание на эталонный цикл, это вполне верный способ утечки памяти. - person MrTJ; 21.02.2014