Я написал большое приложение для iPhone в социальной сети, и одной из самых больших проблем, с которыми я сталкиваюсь, является тот факт, что NSInteger (и все другие типы NS-не-объектов) не являются гражданами первого класса. Эта проблема связана с тем, что, очевидно, у них нет представления для значения nil.
Это создает две основные проблемы:
- Тонны накладных расходов и непрозрачность для преобразования в NSNumber и из него при хранении/извлечении из коллекции.
- Невозможно представить nil. Зачастую я хочу иметь возможность представлять "неустановленное" значение.
Один из способов решить это - использовать NSNumber все время, но это очень запутанно. В объекте модели пользователя у меня было бы около 20 различных NSNumbers, и не было бы простого способа определить, является ли каждый из них float, integer, bool и т.д.
Итак, вот мои мысли о потенциальных решениях и плюсах/минусах. Я не продаюсь никому из них, поэтому я подумал, что попрошу обратной связи и/или альтернативных решений этой проблемы.
- Продолжайте использовать типы NSInteger и просто используйте NSIntegerMax для представления nil.
PRO - Меньше памяти наверх
PRO - Четкая печать
CON - NSIntegerMax на самом деле ничто. Если программисты не внимательны или не знают этого соглашения, недопустимые значения могут просачиваться в уровень отображения.
CON - Невозможно сохранить их в коллекции без конверсий. - Использовать NSNumber и обозначать типы с использованием венгерской нотации (например, NSNumber fHeight, NSNumber iAge)
PRO - первоклассные граждане
Проблема PRO-Nil решена
CON - Увеличение объема памяти
CON - Lose проверка типа компилятора
CON - венгерская нотация спорна - Напиши свои собственные первообразные типы примитивных объектов (подумайте о Java http://developer.android.com/reference/java/lang/Integer.html)
PRO - первоклассные граждане
Проблема PRO-Nil решена
PRO - Сохраняет проверку типа компилятора
PRO - Объекты будут проще NSNumber. Внутреннее хранилище будет специфичным для типа данных.
CON - Увеличение объема памяти
CON - жертвует немного переносимости кода и совместимости
Ищете убедительный аргумент в пользу одного из этих методов, или того, о котором я не думал, если у вас его есть.
UPDATE
Я пошел вперед и начал проект с открытым исходным кодом (Apache 2.0), в который я буду тянуть ряд наших внутренних классов, поскольку у меня есть время. В настоящее время он включает обертки объектов для некоторых наиболее распространенных типов данных (BOOL, CGFloat, NSInteger, NSUInteger). Мы решили сделать это, потому что он обновляет эти типы данных до первоклассных граждан со строгой типизацией. Может быть, вы не согласны с этим подходом, но это сработало для нас, поэтому не стесняйтесь использовать его, если хотите.
Я добавляю другие классы, которые мы использовали для использования, включая кеш LRU с поддержкой диска, объект "Pair", пул с низкой памятью и т.д.