2015-04-16 3 views
0

Я изо всех сил пытаюсь найти мой предикат, вероятно, недостаток словаря.Поиск в массиве разных объектов

У меня есть (вид) слабых конструкций здесь, что мой крайний срок не позволяет мне слишком сильно меняться, и ситуация следующая.

Я ищу в таблице contacts И users, здесь есть два объекта, представляющих интерес. Поиск работает отлично, когда есть только контакты (и ни один из перечисленных объектов не является пользователем).

Теперь, если это произойдет (что будет очень часто), что некоторые из этих контактов являются пользователями, когда я просматриваю табличное представление, мой предикат-ключ не совпадает, и я, очевидно, получаю исключение.

Как я мог бы пойти по этому пути, зная, что я хочу, чтобы поиск по-прежнему включал всех. (У меня есть план резервного копирования, где я просто удаляю пользователей из функции поиска, и это работает как шарм).

Я попытался с помощью OR в моем сказуемого, например:

@"compositeName contains[c] %@ OR name contains[c] %@" //(where %@ is my search string) 

, но это не достаточно, чтобы пропустить тот факт, что мой контакт имеет «compositeName» и мой пользователь имеет «имя», которое вызывает исключение.

Я не хочу изменять имя ключа моих пользователей в «составное имя», потому что это подразумевает переустановку приложения для всех моих бета-тестеров, которое (из-за крайних сроков и содержимого, созданного приложением) также невозможно , Если у них нет возможности использовать новую модель данных без переустановки, я бы сделал это и просто назвал их «составным именем». (или «имя»).

Я использую данные ядра, и массив полон NSManagedObject (пользователя & типов контактов).

Любая идея?

EDIT 1: Это хорошая идея?

Я думаю о разделении массивов, если есть пользователи, а затем использовать разные предикаты в обоих, затем, наконец, объединить их снова и показать эти результаты. Но похоже, что много обработки и, возможно, есть что-то более эффективное?

EDIT 2: Сбой журнал

*** Нагрузочное приложение из-за неперехваченное исключение 'NSUnknownKeyException', причина: «[valueForUndefinedKey]: сущность Пользователь не значение ключа кодирования совместимого для ключа "compositeName" «.

EDIT 3: проверка класса

Согласно комментариям и другим сообщениям на стеке, вы можете добавить проверку состояния, а также делать проверки класса в предикате. Теперь я попытался объединить оба, написав это:

@"((className == %@) name contains[c] %@) OR ((className == %@) compositeName contains[c] %@)", @"User",searchText, @"Contact", searchText 

Это неправильный формат. Это первый раз, когда я играю с предикатами, так что если у вас есть какие-либо подсказки, как написать предикат, который говорит

(If class = User, then name contains [c], if class = Contact, then compositeName contains [c]) 
+0

ли вы скопировать полный предикат? Если это так, вы также должны добавить '% @' для поля имени: '@" составное имя содержит [c]% @ ИЛИ имя содержит [c]% @ "' – tbaranes

+0

черт возьми, я надеюсь, что это просто, его нет в моем код тоже. –

+0

Нет, он по-прежнему терпит крах, но% @ отсутствует, так что спасибо: D Исключение очень ясное, мой «Пользователь» не является кодировкой ключевого значения для ключа «составное имя». –

ответ

2

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

Если вы комбинируете тест класса объекта с использованием И с тестом name/compositeName, вы можете избежать этой проблемы - сначала проверив класс, предикат пропустит второй тест (для имени/составного имени), поскольку первый тест уже возвращено false - это делает бессмысленным проверку второго предложения AND.

Вы можете использовать предикат что-то вроде

@"(className == %@ AND name contains[c] %@) OR (className == %@ AND compositeName contains[c] %@)",[User className],searchString,[Contact classname],searchString 
Смежные вопросы