Я сталкиваюсь с проектными решениями как это часто и борюсь немного; я ищу некоторые другие перспективы.
Я часто хочу сохранить списки или раздать блоки состояния, которые являются в основном просто множествами значений. Значения имеют тенденцию быть типами примитивов: плавания, NSTimeIntervals, CGPoints, и т.д.
Мой первый наклон состоит в том, чтобы часто создавать структуры C для этих наборов свойств, например.
typedef struct _STATE {
float foo;
NSTimeInterval elapsed;
CGPoint point;
} STATE;
и т.д.
Но структуры C не играют приятно с собственными классами набора Какао (NSArray
, NSSet
, NSDictionary
), и использование сверхмногих из них для отслеживания большого количества состояния чувствует, что работает против мелкой частицы отдыха моего благоприятного для какао кода - я заканчиваю тем, что имел и непосредственно руководящие массивы структур и раздал указатели структуры в сообщениях, и т.д.
С другой стороны, так как необработанная производительность не обязательно очень важна, я мог закодировать эти значения в NSDictionary, перенеся их всех в NSValue
или NSNumber
, но получающийся синтаксис является едва кратким, и немного хрупким, требуя типа и правильности имени во времени выполнения и для вставки и для поиска:
[stateDict setObject:[NSNumber numberWithFloat:foo] forKey:@"bar"];
...
float something = [[stateDict objectForKey:@"bar"] floatValue];
и некоторые типы, как NSTimeInterval, только могут использоваться с некоторым (спорным) хакерством (преобразование типа для удвоения в этом случае).
Наконец, я мог создать контейнерные объекты только для данных с данными члена парламента, не занимающего официального поста и только методами считывания/методами set. (Их назвали бы "бобами" в Java.) Они являются более краткими к доступу, чем словари, большему количеству Какао, чем структуры, но чувствуют себя подобно излишеству мне, особенно если мне только нужны они как "внутренние классы", которые используются для управления состоянием, внутреннего к типу отдельного объекта.
Как делают Вы, великая общественность программирования Какао, делаете это?
В зависимости от ситуации я запускаю либо классы NSDictionary для произвольных данных, либо создаю классы контейнеров (теги @ property / synthesize в Objective C делают это действительно просто). Используя ObjC для файла заголовка:
@interface StateObject : NSObject {
NSNumber *foo;
NSTimeInterval *elapsed;
CGPoint point;
}
@property (retain) NSNumber *foo;
@property (retain) NSTimeInterval *elapsed;
@property (copy) CGPoint point;
@end
Затем можно использовать @synthesize
в файле .m для автоматического создания установщиков / получателей. Затем, пока анонимные NSNumbers все еще злобны, вы можете сделать:
myStateObject.foo = [NSNumber numberWithFloat:7.0];
Это должно снять большую часть боли и позволить вам использовать классы коллекции Какао для лучшего перемешивания данных.
Не обязательно одобрять этот подход как «лучший», но между вашими предложениями есть золотая середина: создайте структуры C для хранения информации, а затем оберните структуры в объектах NSValue
, когда вам нужно поместить их в структуры данных Какао. Вы можете увидеть, как UIKit делает это в некоторых случаях с помощью таких структур, как CGPoint
в уведомлениях (и я уверен, что AppKit также делает).
См. «Использование значений» в Разделы программирования чисел и значений для Какао для получения дополнительной информации.