Управляемые объекты
Эта статья предоставляет основную информацию о том, что является управляемым объектом, как его данные хранятся, как Вы реализуете пользовательский класс управляемых объектов, объектные проблемы жизненного цикла и сбой. Существует несколько других статей в Базовом Руководстве по программированию Данных, описывающих другие аспекты использования управляемых объектов:
Основы
Управляемые объекты являются экземплярами NSManagedObject
класс, или подкласса NSManagedObject
, это представляет экземпляры объекта. NSManagedObject
универсальный класс, реализующий все основное поведение, требуемое управляемого объекта. Можно создать пользовательские подклассы NSManagedObject
, несмотря на то, что это часто не требуется. Если Вам не нужна никакая пользовательская логика для данного объекта, Вы не должны создавать пользовательский класс для того объекта. Вы могли бы реализовать пользовательский класс, например, чтобы обеспечить пользовательское средство доступа или методы проверки, использовать нестандартные атрибуты, указать зависимые ключи, вычислить полученные значения или реализовать любую другую пользовательскую логику.
Управляемый объект связан с описанием объекта (экземпляр NSEntityDescription
) это обеспечивает метаданные об объекте (включая имя объекта, который объект представляет и имена его атрибутов и отношений), и с контекстом управляемого объекта, отслеживающим изменения в графе объектов.
Управляемый объект также связан с контекстом управляемого объекта («контекст»). В данном контексте управляемый объект обеспечивает представление записи в персистентном хранилище. В данном контексте, для данной записи в персистентном хранилище, может быть только один соответствующий управляемый объект, но могут быть многократные контексты каждый содержащий отдельный управляемый объект, представляющий ту запись. Другими словами, существует к - одно отношение между управляемым объектом и записью данных, которую оно представляет, но к - многие отношение между рекордными и соответствующими управляемыми объектами.
Свойства и хранение данных
В некотором отношении, NSManagedObject
действия как словарь — это - универсальный контейнерный объект, эффективно обеспечивающий хранение для свойств, определенных его связанным NSEntityDescription
объект. NSManagedObject
предоставляет поддержку для диапазона общих типов для значений атрибута, включая строку, дату и число (см. NSAttributeDescription
для полного изложения). Нет поэтому обычно никакой потребности определить переменные экземпляра в подклассах. Существуют некоторые соображения производительности, чтобы принять во внимание, используете ли Вы большие объекты двоичных данных — посмотрите Большие Объекты данных (BLOBs).
Нестандартные атрибуты
NSManagedObject
предоставляет поддержку для диапазона общих типов для значений атрибута, включая строку, дату и число (см. NSAttributeDescription
для полного изложения). По умолчанию, NSManagedObject
хранит его свойства, поскольку объекты во внутренней структуре, и в общих Базовых Данных являются более эффективной работой с хранением под ее собственным управлением вместо того, чтобы использовать пользовательские переменные экземпляра.
Иногда Вы хотите использовать типы, не поддерживающиеся непосредственно, такие как цвета и структуры C. Например, в графическом приложении Вы могли бы хотеть определить Прямоугольный объект, имеющий цвет атрибутов и границы, которые являются экземпляром NSColor
и NSRect
структура соответственно. Это может потребовать, чтобы Вы создали подкласс NSManagedObject
, и описан в Нестандартных Персистентных Атрибутах.
Даты и время
NSManagedObject
представляет использование атрибутов даты NSDate
объекты, и времена хранилищ внутренне как NSTimeInterval
значение начиная с базисной даты (который имеет часовой пояс GMT). Часовые пояса не явно сохранены — действительно необходимо всегда представлять Базовый атрибут даты Данных в GMT, этот способ, которым поиски нормализованы в базе данных. Если необходимо сохранить информацию о часовом поясе, необходимо сохранить атрибут часового пояса в модели. Это может снова потребовать, чтобы Вы создали подкласс NSManagedObject
.
Пользовательские классы управляемых объектов
В сочетании с описанием объекта в модели управляемого объекта, NSManagedObject
обеспечивает богатый набор способов поведения по умолчанию включая поддержку произвольных свойств и проверки значения. Существует, тем не менее, много причин, почему Вы могли бы хотеть разделить на подклассы NSManagedObject
реализовать пользовательские опции. Существуют также, однако, некоторые вещи избежать при разделении на подклассы. Также важно знать, что Базовые Данные управляют жизненным циклом смоделированных свойств.
Методы переопределения
NSManagedObject
самостоятельно настраивает много функций NSObject
так, чтобы управляемые объекты могли быть должным образом интегрированы в Базовую Информационную инфраструктуру. Базовые Данные полагаются NSManagedObject
реализация следующих методов, которые Вы не должны поэтому переопределять: primitiveValueForKey:
, setPrimitiveValue:forKey:
, isEqual:
, hash
, superclass
, class
, self
, zone
, isProxy
, isKindOfClass:
, isMemberOfClass:
, conformsToProtocol:
, respondsToSelector:
, managedObjectContext
, entity
, objectID
, isInserted
, isUpdated
, isDeleted
, и isFault
. Вы отговорены переопределить description
— если этот метод запускает отказ во время работы отладки, результаты могут быть непредсказуемыми — и initWithEntity:insertIntoManagedObjectContext:
. Вы не должны обычно переопределять методы кодирования значения ключа такой как valueForKey:
и setValue:forKeyPath:
.
В дополнение к методам Вы не должны переопределять, существуют другие, которые, если Вы действительно переопределяете Вас, должны вызвать реализацию суперкласса сначала, включая awakeFromInsert
, awakeFromFetch
, и методы проверки такой как validateForUpdate:
.
Смоделированные свойства
Базовые Данные динамично генерируют эффективный общедоступный, и примитивный получают и устанавливают методы доступа атрибута и методы доступа отношения для свойств, определяющихся в объекте соответствующей модели управляемого объекта управляемого объекта. Как правило, поэтому Вы не должны писать пользовательские методы доступа для смоделированных свойств.
В подклассе управляемого объекта можно объявить свойства для смоделированных атрибутов в интерфейсном файле, но Вы не объявляете переменные экземпляра:
@interface MyManagedObject : NSManagedObject |
@property (nonatomic, strong) NSString *title; |
@property (nonatomic, strong) NSDate *date; |
@end |
Заметьте, что свойства объявляются как nonatomic
, и strong
. Даже если класс значения принимает, по причинам производительности Базовые Данные обычно не копируют объектные значения NSCopying
протокол.
В файле реализации Вы указываете свойства как dynamic
:
@implementation MyManagedObject |
@dynamic title; |
@dynamic date; |
@end |
Если действительно необходимо реализовать пользовательские методы доступа, существует несколько образцов реализации, за которыми необходимо следовать — посмотрите Методы доступа Управляемого объекта.
Объектный жизненный цикл — инициализация и освобождение
Базовым Данным «принадлежит» жизненный цикл управляемых объектов. Со сбоем и отменой, Вы не можете сделать те же предположения о жизненном цикле управляемого объекта, как Вы были бы стандартного объекта Какао — управляемые объекты может инстанцировать, уничтожить и возродить платформа, как это требует.
Когда управляемый объект создается, он инициализируется со значениями по умолчанию, данными для его объекта в модели управляемого объекта. Во многих случаях набор значений по умолчанию в модели может быть достаточным. Иногда, однако, можно хотеть выполнить дополнительную инициализацию — возможно, использование динамических значений (таких как текущая дата и время), который не может быть представлен в модели.
В типичном классе Какао Вы обычно переопределяете определяемый инициализатор (часто init
метод). В подклассе NSManagedObject
, существует три различных способа, которыми можно настроить инициализацию — путем переопределения initWithEntity:insertIntoManagedObjectContext:
, awakeFromInsert
, или awakeFromFetch
. Вы не должны переопределять init
. Вы отговорены переопределить initWithEntity:insertIntoManagedObjectContext:
поскольку изменения состояния, внесенные в этом методе, не могут быть должным образом интегрированы с отменой и восстановлением. Два других метода, awakeFromInsert
и awakeFromFetch
, позвольте Вам дифференцироваться между двумя различными ситуациями:
awakeFromInsert
вызывается только один раз во времени жизни объекта — когда оно сначала создается.awakeFromInsert
сразу вызывается после вызоваinitWithEntity:insertIntoManagedObjectContext:
илиinsertNewObjectForEntityForName:inManagedObjectContext:
. Можно использоватьawakeFromInsert
инициализировать специальные значения свойств по умолчанию, такие как дата создания объекта, как проиллюстрировано в следующем примере.- (void) awakeFromInsert
{
[super awakeFromInsert];
[self setCreationDate:[NSDate date]];
}
awakeFromFetch
когда объект повторно инициализируется от персистентного хранилища (во время выборки), вызывается.Можно переопределить
awakeFromFetch
к, например, устанавливают переходные значения и другие кэши. Обработка изменения явно отключена вокругawakeFromFetch
так, чтобы можно было удобно использовать общедоступные методы доступа набора без dirtying объект или его контекст. Это означает, однако, что Вы не должны управлять отношениями, поскольку изменения не будут должным образом распространены к целевому объекту или объектам. Вместо этого можно переопределитьawakeFromInsert
или используйте любой из связанных методов цикла выполнения такой какperformSelector:withObject:afterDelay:
.
Вы не должны обычно переопределять dealloc
очистить переходные свойства и другие переменные. Вместо этого необходимо переопределить didTurnIntoFault
. didTurnIntoFault
когда объект превращен в отказ и сразу до фактического освобождения, вызывается автоматически Базовыми Данными. Вы могли бы превратить управляемый объект в отказ в частности для сокращения памяти наверху (см. Сокращающую Память Наверху), таким образом, важно гарантировать, чтобы Вы должным образом выполнили операции по зачистке местности в didTurnIntoFault
.
Проверка
NSManagedObject
обеспечивает непротиворечивые рычаги для проверки значений свойств и межзначений свойств. Вы обычно не должны переопределять validateValue:forKey:error:
, вместо этого необходимо реализовать методы формы validate<Key>:error:
, как определено NSKeyValueCoding
протокол. Если Вы хотите проверить межзначения свойств, можно переопределить validateForUpdate:
и/или связанные методы проверки.
Вы не должны вызывать validateValue:forKey:error:
в пользовательских методах проверки свойства — если Вы делаете так, Вы создадите бесконечный цикл когда validateValue:forKey:error:
вызывается во время выполнения. При реализации пользовательских методов проверки Вы не должны обычно вызывать их непосредственно. Вместо этого необходимо вызвать validateValue:forKey:error:
с надлежащим ключом. Это гарантирует, что применяются любые ограничения, определенные в модели управляемого объекта.
Если Вы реализуете пользовательские методы проверки межсвойства (такой как validateForUpdate:
), необходимо вызвать реализацию суперкласса сначала. Это гарантирует, что также вызываются отдельные методы проверки свойства. Если существуют многократные отказы проверки в одной работе, необходимо собрать их в массиве и добавить массив — использование ключа NSDetailedErrorsKey
— к userInfo словарю в NSError
возразите, что Вы возвращаетесь.
Сбой
Управляемые объекты обычно представляют данные, сохраненные в персистентном хранилище. В некоторых ситуациях управляемый объект может быть «отказом» — объект, значения свойств которого еще не были загружены из внешнего хранилища данных — дополнительную информацию см. в Faulting и Uniquing. При доступе к персистентным значениям свойств отказ «огни» и данные получен от хранилища автоматически. Это может быть сравнительно дорогим процессом (потенциально требующий цикла обработки к персистентному хранилищу), и можно хотеть избежать излишне запускать отказ (см. Дающее сбой Поведение).
Несмотря на то, что description
метод не заставляет отказ стрелять при реализации пользовательского description
метод, получающий доступ к персистентным свойствам объекта, это заставит отказ стрелять. Вы строго отговорены переопределить description
таким образом.
Нет никакого способа загрузить отдельные атрибуты управляемого объекта по мере необходимости. Для образцов для контакта с большими атрибутами посмотрите Большие Объекты данных (BLOBs).