У меня есть серия моделей для моего приложения. Во всех этих моделях есть (будут) около 200 или 300 переменных экземпляра. Приложение хранит свои постоянные данные на веб-сервере (MySQL - но я думаю, что эта часть не имеет значения). Всякий раз, когда обновляется модель iVar, мне нужно сделать звонок на сервер, чтобы обновить соответствующее значение для этого iVar.Использование одного сеттера для всех моделей iVars
Моя текущая стратегия модели (заголовочный файл):
@interface MyModel : NSObject {
NSString * firstName;
NSString * lastName;
}
@property (readwrite, copy) NSString * firstName;
@property (readwrite, copy) NSString * lastName;
@end
(файл реализации):
@implementation MyModel
@synthesize firstName;
@synthesize lastName;
-(id)init {
[super init]
[self setFirstName:@"George"];
[self setLastName:@"Kastanza"];
return self;
}
-(void)setFirstName:(NSString *)aName {
// call method to update server with new value here
firstName = aName;
}
-(void)setLastName:(NSString *)aName {
// call method to update server with new value here
lastName = aName;
}
@end
Проблема заключается в том, что если у меня есть 200 или 300 Ивара все необходимости идти через тот же запрос обновления на сервер, что означает запись лота сеттеров. Более того, если мне нужно внести изменения в вызов метода, мне придется обновлять каждый метод в каждом сетевом устройстве во всем приложении.
Есть ли способ, с помощью которого я мог запускать каждый набор iVar с помощью метода сначала, прежде чем устанавливать?
Я думал о наличии только NSMutableDictionary
на модельный объект для хранения всех iVar, но это абстрагирует сеттеры и геттеры и может создать большой объем памяти для столь большого количества словарей. Однако это делается так, что каждый раз, когда устанавливается словарь, я могу передать его одним методом.
Как я понимаю, динамическое добавление iVar во время выполнения к объектной модели считается плохой из-за указателя, ссылающегося на любые подклассы, которые могут зависеть от модели (указатель подкласса не получает смещение, если полная перекомпиляция готово).
Любые идеи и предложения, которые были высоко оценены.
Update
На основе рекомендации Оле здесь решение (хотя он использует немного больше кода, чем несколько строк к сожалению) ...
В модели я добавил метод, который я могу когда мне нужно. Я не вызывал метод непосредственно из init, потому что добавление целой группы результатов, возвращаемых с сервера, вызывало бы наблюдателей для каждого добавленного объекта. Поэтому я вызываю метод после Я инициализировал и обновлял первый захват с сервера.
Вот код ...
-(void)registerObservers {
[self addObserver:self
forKeyPath:@"firstName"
options:NSKeyValueObservingOptionNew
context:NULL];
[self addObserver:self
forKeyPath:@"lastName"
options:NSKeyValueObservingOptionNew
context:NULL];
}
Затем я добавляю наблюдатель модели:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"firstName"]) {
// Do whatever I need to do
}
if ([keyPath isEqual:@"lastName"]) {
// Do whatever I need to do
}
}
В моей реальной реализации я также случиться, чтобы отправлять уведомления об объекте установлен в self
так что я могу обновить все, что должно случиться, но не обращает внимания (например, материал в NSArrayControllers
).
благодарит за отзыв. Я не уверен, что действительно что-то покупает, потому что тогда я буду писать наблюдателя для каждого iVar вместо пары строк для кода.То, что я надеялся, заключалось в том, чтобы сделать что-то вроде подкласса @synthesize, чтобы каждый сеттер прошел через один пользовательский метод на моей объектной модели, прежде чем передаваться самому сеттеру. – Hooligancat
Нет, вы бы написали 400 строк кода шаблона (200, чтобы зарегистрировать себя как наблюдателя и 200, чтобы удалить себя как наблюдателя), но фактический метод, вызываемый при изменении значения, всегда один и тот же. И используя среду выполнения Obj-C для перечисления всех свойств вашего класса, вы также можете свести код шаблона к циклу (см. 'Class_copyPropertyList',' property_getName' и 'property_getAttributes'). –
OK - теперь мне нравится подход! :-) Перечисление через объекты, чтобы получить свойства класса, может быть гладким ответом на мои молитвы. Благодаря!! – Hooligancat