Должен ли я использовать == или [NSManagedObject isEqual:] для сравнения управляемых объектов в том же контексте? - PullRequest
18 голосов
/ 09 июня 2011

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

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

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

Ответы [ 3 ]

20 голосов
/ 09 июня 2011

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

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

18 голосов
/ 23 марта 2012

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

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

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

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

7 голосов
/ 11 марта 2016

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

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

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

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

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

Наконец, пара полезных методов - NSManagedObjectID isTevenID и NSManagedObjectContext receivePermanentIDsForObjects: error:.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...