6

Поскольку наша кодовая база созревает, мне начинает не нравиться шаблон передачи словарей как способ упаковывать информацию для передачи сообщений или, что еще хуже, аргументов функции. Это требует, чтобы функция отправки и получения имела недокументированный API строковых литералов.Лучше, чем передавать NSDictionaries в качестве параметров?

..in some function.. 
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: 
         thisObject, @"thisKey", 
         thatObject, @"thatKey", 
         nil]; 

[[NSNotificationCenter defaultCenter] postNotificationName:@"MY_NOTIFICATION" object:nil userInfo:info]; 
.... 

, а затем в слушателе someClass «s

- (void)someClassListener:(NSNotification *)notification { 
    NSDictionary *info = [notification userInfo]; 

    ThisObject *ob1 = [info objectForKey:@"thisKey"]; 
    ThatObject *ob2 = [info objectForKey:@"thatKey"]; 
} 

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

И скажем, что у вас есть функция, которая требует 15 аргументов, вы не собираетесь делать функцию с 15 параметрами, было бы намного проще (хотя и менее читаемо) просто передать словарь, но теперь у вас есть такой же проблема, как указано выше.

Я играл с созданием «классов сообщений» в этих заголовочных файлах этого класса (т.е. два интерфейса в одном заголовке), а класс сообщений - это просто список объектов, которые вы определяете и отправляете методу, который создает более сильный контракт, но это кажется неправильным.

Было бы замечательно, если бы я мог сделать что-то вроде typeDef объект параметра в заголовке, но не поддерживает NSObject Вот только такие вещи, как int или float т.д.

По существу я пытаюсь создать более сильный контракт между отправителем сообщения и приемником сообщений, будь то функции или уведомления.

ответ

4

Вы можете определить константы для ключей. Например, см. Документы для UIKeyboardDidShowNotification для примера. Существует ссылка на все ключи, которые можно использовать для получения информации об уведомлении.

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

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

+0

Я упоминаю константы для ключей как не хорошее решение, потому что вам все равно нужно искать, что такое ключ, и не создавать сильный контракт, для чего будет значение (объект), больше похоже на предложение. Инкапсулирование данных в класс было направлением, которое я изучал, но кажется громоздким создать класс для каждого сообщения, которое я хочу передать, будь то 2 аргумента равны 10, не согласны ли вы? – Shizam

+0

@Shizam, Если эти сообщения будут помещены в разные словари, тогда вам, вероятно, понадобится более одного класса. Но если вы говорите о сообщениях, которые иногда передают два ключа из словаря, а иногда и 10, то это все равно будет только одним классом. – rdelmar

+0

@rdelmar Что я имею в нашей программе, у нас, вероятно, есть 10-15 уникальных уведомлений, каждому из этих уведомлений потребуется свой собственный класс, чтобы определить его свойства для сообщения и т. Д. – Shizam

2

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

Дайте объекту параметра простой API, который позволяет устанавливать оба класса и получать определенные поля - setThisKey: и getThisKey. Это, по сути, документирует API между методами и классами.

Далее, найдите возможности для перемещения функциональности в объект параметра.Например, если у вас есть что-то вроде этого:

param.fieldSize=[self.data size]; 
param.fieldColor=[self.data color]; 
param.flavor=[self.data lookUpTheRecipe] 

Вы можете инкапсулировать все это с

[param withField: self.data]; 

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

+0

Я упоминаю об этом как о решении, которое я рассматривал, проблема, которую я вижу, заключается в создании объекта параметра для каждого сообщения, кажется громоздким. Также кажется, что место, которое помещает этот объект, находится в заголовке класса, который «владеет» сообщением таким образом, что у вас есть два интерфейса в одном заголовке, который, кажется, нахмурился. – Shizam

+0

Вы можете часто использовать один объект параметра среди нескольких связанных методов. –

+1

Я не вижу возражений против добавления интерфейсов к вспомогательным объектам в заголовок класса. Но ваша цель с объектом параметра - добавить к этому объекту много полезного поведения, а не просто обернуть некоторые данные. Итак, в конечном итоге объект параметров может заслужить свое место в мире. Такие классы, как NSURL, начинаются именно так. –

0

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


Относительно использования отправителя уведомления? Например, ваш объект Task завершен и отправляет уведомление. Приемник использует отправителя для доступа sender.result, sender.error, sender.anything.


Если вы хотите более сильный контакт между этими объектами (отправитель/получатель) может быть, вы должны использовать какой-то другой способ общения вместо NSNotifications.

Некоторые альтернативы:

  • делегат (или какой-то другой прямой вызов метода)
  • блоки
  • мишень + действие

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

+0

Мы также используем делегаты и блоки, я просто использовал NSNotifications в качестве примера, где его легко увидеть проблему. У меня все еще есть эта проблема с блоками и т. Д., Но я начинаю думать, что создание объектов параметров, содержащих параметры, в значительной степени является единственным способом сделать это. – Shizam

Смежные вопросы