Подтвердить что ты не робот

Должен ли я использовать == или [NSManagedObject isEqual:] для сравнения управляемых объектов в том же контексте?

Пусть говорят, что переменные A и B содержат экземпляры управляемых объектов в одном и том же контексте управляемых объектов. Мне нужно убедиться, что они связаны с одной и той же "записью" в постоянном хранилище. В разделе Faulting and Uniquing в Руководстве по программированию основных данных говорится, что:

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

Из этого видно, что для моей цели достаточно сравнения указателей. Или имеет смысл использовать isEqual: сравнивать управляемые объекты в том же контексте?

4b9b3361

Ответ 1

Используйте ==, чтобы определить, указывают ли два указателя на один и тот же объект. Используйте -isEqual, чтобы определить, являются ли два объекта "равными", где понятие равенства зависит от сравниваемых объектов. -isEqual: обычно сравнивает значения, возвращаемые методом -hash. Ранее я писал, что возможно, что -isEqual: может возвращать значение true, если два управляемых объекта содержат одинаковые значения. Это явно не так. В документах есть некоторые предостережения о том, что значение хеша для изменяемого объекта не изменяется, пока оно находится в коллекции, и что знание того, является ли данный объект в коллекции, может быть затруднено. Кажется уверенным, что хэш для управляемого объекта не зависит от данных, которые содержит этот объект, и гораздо более вероятно, что он связан с чем-то неизменным относительно объекта; значение объекта -objectID кажется вероятным кандидатом.

Учитывая все это, я меняю свое мнение;-). Каждая запись представлена ​​только один раз в заданном контексте, поэтому ==, вероятно, безопасен, но -isEqual:, похоже, лучше выражает ваше намерение.

Ответ 2

Сравнение указателей отлично подходит для объектов, получаемых из одного контекста управляемого объекта, документация по уникальной цитате promises.

ObjectID следует использовать для проверки равенства объектов в контекстах управляемых объектов.

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

Итак, семантика теста равенства для управляемых объектов просто "указывает на один и тот же объект (запись) в контексте управляемого объекта" и будет сравнивать значение false для объектов в разных контекстах.

Ответ 3

Предупреждение. Поскольку NSManagedObject isEqual сравнивает идентификаторы объектов, сравнение может завершиться неудачно, если один экземпляр использует временный идентификатор объекта, а другой экземпляр использует постоянный идентификатор объекта.

Справочная информация. Когда создается NSManagedObject, ему назначается временный идентификатор объекта. Он преобразуется в постоянный объектID, когда NSManagedObject фактически сохраняется в хранилище. Вы можете увидеть разницу, если вы печатаете идентификатор объекта:

x-coredata:///MyEntity/t03BF9735-A005-4ED9-96BA-462BD65FA25F118 (временный идентификатор)

x-coredata://EB8922D9-DC06-4256-A21B-DFFD47D7E6DA/MyEntity/p3 (постоянный идентификатор)

Когда объектID преобразуется в постоянный, экземпляры NSManagedObject в других потоках и коллекциях не обновляются. Поэтому, если вы помещаете NSManagedObject в NSArray, когда у него есть временный идентификатор объекта, использование методов типа containsObject не удастся, если вы попытаетесь найти объект с постоянным идентификатором объекта. Запомнить containsObject использует isEqual.

Наконец, несколько полезных методов: NSManagedObjectID isTemporaryID и NSManagedObjectContext getPermanentIDsForObjects: error:.