Я не уверен, что именно ваш вопрос. Существует шаблон проектирования Singleton, который гарантирует, что у вас может быть только один экземпляр данного класса. Это не совсем то, что вам нужно, но есть вариант шаблона Singleton, называемый Multiton, который хранит один экземпляр класса для данного ключа (в вашем случае, имя состояния). Вот как работают [NSNull null]
(синглтон) или NSNumber
(мультитон):
NSLog(@"%i", [NSNull null] == [NSNull null]); // 1
NSLog(@"%i", [NSNumber numberWithInt:42] == [NSNumber numberWithInt:42]); // 1
Но эти шаблоны очень легко использовать неправильно, и, вероятно, было бы гораздо лучше, если бы вы могли решить проблему без них. Нет проблем с тем, чтобы все указатели состояния ссылались на один и тот же экземпляр. То есть существует только проблема создания целого графа объектов. Это легко, если вы сохраните свойства изменяемыми:
State *oregon = [[State alloc] initWithName:@"Oregon"];
State *washington = [[State alloc] initWithName:@"Washington"];
[oregon setNeighbouringStates:[NSSet setWithObject:washington]];
[washington setNeighbouringStates:[NSSet setWithObject:oregon]];
И так далее. Еще лучшим решением вашей проблемы может быть другая модель данных, другой способ представления соседних отношений. Но это зависит от ваших требований.
Вы говорите в комментариях, что у вас есть состояния в словаре. Ключами являются имена состояний, а значениями являются массивы имен соседних состояний? Если это так, вы можете сделать что-то вроде этого:
typedef State* (^StateBuilder)(NSString *stateName);
NSDictionary *input = …;
NSMutableDictionary *states = [NSMutableDictionary dictionary];
StateBuilder getState = ^(NSString *stateName) {
State *state = [states objectForKey:stateName];
if (!state) {
state = [[State alloc] initWithName:stateName];
[states setObject:state forKey:stateName];
}
return state;
};
for (NSString *stateName in [input allKeys]) {
State *state = getState(stateName);
NSMutableSet *neighbours = [NSMutableSet set];
for (NSString *neighbourName in [input objectForKey:stateName])
[neighbours addObject:getState(neighbourName)];
[state setNeighbours:neighbours];
}
Результаты будут в итоге [states allValues]
. Конечно, блок voodoo не нужен, вы можете превратить словарь states
в переменную экземпляра и использовать обычный метод вместо блока.