Лучшая альтернатива объектам Objective-C "только для данных"? - PullRequest
7 голосов
/ 16 февраля 2010

Я часто сталкиваюсь с выбором дизайна и немного борюсь; Я ищу другие перспективы.

Я часто хочу вести списки или передавать куски состояния, которые в основном являются просто наборами значений. Значения имеют тенденцию быть примитивными типами: float, 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, могут использоваться только с некоторыми (спорными) хакерами (в этом случае приведение к типу удваивается).

Наконец, я мог бы создавать объекты-контейнеры только для данных с закрытыми данными-членами и только получателями / установщиками. (В Java они называются «bean-компонентами».) Они более лаконичны для доступа, чем словари, больше какао, чем структуры, но мне кажется излишним, особенно если они нужны мне только как «внутренние классы», которые используются для управления состоянием внутренний для одного типа объекта.

Как вы, великие программисты Cocoa, делаете это?

Ответы [ 2 ]

14 голосов
/ 16 февраля 2010

В зависимости от ситуации я запускаю либо с использованием классов 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 <variable> в файле .m для автоматического создания сеттеров / геттеров.Затем, в то время как анонимные номера NSN по-прежнему ужасны, вы можете сделать следующее:

myStateObject.foo = [NSNumber numberWithFloat:7.0];

Это должно снять большую часть боли и позволить вам использовать классы сбора Cocoa для лучшей перетасовки данных.

2 голосов
/ 16 февраля 2010

Не обязательно одобрять этот подход как «лучший», но между предложениями есть нечто среднее: создайте структуры C для хранения информации, а затем оберните структуры в NSValue объекты, когда вам нужно поместить их в данные Какао структур. Вы можете видеть, что UIKit делает это в некоторых случаях со структурами, такими как CGPoint в уведомлениях (и я уверен, что AppKit также делает).

См. "Использование значений" в Темы программирования чисел и значений для какао для получения дополнительной информации.

...