2012-06-06 1 views
2

Просто найдите небольшую обратную связь, если это плохая идея для совместного использования Контекста управляемого объекта.Использование #DEFINE для совместного использования управляемого объекта Контекст

В файле MyApp-Prefix.pch я добавил следующее:

#import "AppDelegate.h" 
#define MOC [(AppDelegate*)[UIApplication sharedApplication].delegate managedObjectContext] 

Затем, когда мне нужно получить доступ к контексту я делаю следующее (только пример):

[MOC deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]]; 

Это, кажется, отлично работает , но это также кажется слишком легким, тем более, что я не вижу его нигде. Это плохой дизайн?

Спасибо за любую обратную связь

+0

Хороший способ представить глобальную переменную ... которая, в свою очередь, вводит скрытые зависимости в ваш код, затрудняет реорганизацию и трудно тестировать изолированно. –

+0

Оба ответа ниже касаются обсуждаемого вопроса о шаблоне дизайна [здесь] (http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html). Хорошо стоит прочитать, когда возникает такой вопрос. – Swizzlr

ответ

2

Вместо макроса компилятора (что может привести к неожиданности иногда) я обычно определяю метод класса на моем приложении делегата, как это:

+ (AppDelegate *)sharedDelegate 
{ 
    return [[UIApplication sharedApplication] delegate]; 
} 

Тогда, когда мне нужна ссылка на какое-то глобальное состояние, я можно назвать так:

[[[AppDelegate sharedDelegate] managedObjectContext] deleteObject:foo]; 

Если ваше приложение является достаточно сложным, то может быть стоит проблема прохождения вокруг ссылкой на контекст управляемого объекта, а не с помощью глобальной. Если вы это сделаете, вам будет легче реорганизовать и использовать другие методы позже, например, детские контексты для групповых изменений.

Чтобы быть конкретным, это означает, что каждый контроллер представления имеет собственную переменную экземпляра управляемогоObjectContext. Когда вы представляете новый контроллер представлений, вы передаете ссылку: возможно, в пользовательском методе инициализации, возможно, установив свойство. Ни один из ваших классов (кроме, возможно, контроллера корневого представления) никогда не ссылается на ваш глобальный делегат приложения. Таким образом, если у вас было сложное редактирование, вы могли бы дать ему дочерний контекст, где он мог бы сохранять изменения «временно» (чтобы убедиться, что все объекты действительны); если пользователь нажимает кнопку отмены, вы просто отбрасываете весь контекст.

Кроме того, если вы всегда используете глобальный контекст, у вас могут быть ошибки, которые трудно отследить. Например, вид редактирования, который не очищается после себя, оставляет за собой недопустимый объект. Тогда в следующий раз, когда вы отправитесь спасти что-то несвязанное, вы получите сообщение об ошибке! Случилось со мной, не было весело отлаживать.

+0

Спасибо за это, просто для того, чтобы прояснить одну мелочь. Когда люди говорят «передать контекст, а не использовать глобальный», они означают «self.moc = [[AppDelegate sharedDelegate] managedObjectContext]' in viewDidLoad вместо того, чтобы всегда использовать '[[AppDelegate sharedDelegate] managedObjectContext]' непосредственно где вам это нужно? Или это нечто большее, я полагаю, что мне не хватает ключевого момента во всем этом, потому что я не понимаю, почему один из них лучше другого. – Brad

+0

@ br4d Да, у вас отсутствует ключевой момент. :-) Я уточнил свой ответ, дайте мне знать, если это поможет. – benzado

+0

Ahh спасибо, это помогает тонну. – Brad

0

Ничего плохого в таком подходе - но если удалось контекстный объект делегата будет меняться в течение жизни вашей программы, это кажется более разумным и эффективно использовать глобальную переменную. Структура Cocoa AppKit использует второй подход с переменной NSApp, которая установлена ​​в [NSApplication sharedApplication].

 Смежные вопросы

  • Нет связанных вопросов^_^