2010-03-11 5 views
2

У меня есть NSMutableArray, который заполнен объектами строк. Для простоты мы скажем, что объекты - это человек, а каждый объект человека содержит информацию об этом человеке.Сравните NSArray с NSMutableArray, добавляя дельта-объекты в NSMutableArray

Таким образом, у меня будет NSMutableArray, заполняемый с объектами лицо:

person.firstName 
person.lastName 
person.age 
person.height 

И так далее.

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

В настоящее время я создаю NSArray набора результатов, опорожнение NSMutableArray, а затем вновь заселять NSMutableArray с NSArray результатов перед разрушением NSArray объекта.

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

Неэффективность, похоже, заключается в том, что я должен иметь возможность сравнивать два массива и заканчивать фильтрацией NSArray. Затем я мог бы добавить отфильтрованный набор в NSMutableArray. Это означало бы, что я могу просто добавить новые данные в NSMutableArray вместо того, чтобы выбрасывать все и повторно заполнять.

И наоборот, мне нужно будет сделать тот же фильтр в обратном порядке, чтобы увидеть, есть ли записи, требующие удаления с NSMutableArray.

Есть ли способ сделать это более эффективным способом? Я что-то пропустил в документах, где говорится о более простой технике?

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

Любые предложения или помощь очень ценятся.

Update

было бы так же быстро, чтобы сделать быстрое перечисление над каждым сравнением каждого элемента строки, как я иду? Похоже, что это дорогостоящая операция, но с последним быстрым кодом перечисления может быть довольно эффективным ...

Решение

Я заканчивал тем, что с предложением Abizem в. Создание изменчивой копии массива и копия объекта выглядит немного более быстрым, чем использование решения sbooth при работе с большими наборами данных. Оба отлично работали, я просто получил больше преимуществ, используя подход с изменяемой копией. Сказав это, я открыл глаза на NSSet, где раньше не смотрел.

Спасибо за отзыв.

+2

Почему бы не проверить его и не увидеть? Не преждевременно оптимизируйте. –

+0

В процессе :-) Я обновлю свои выводы *, но * если кто-то это сделал и знает ... ну ... :-) – Hooligancat

ответ

2

Два очка.

  1. Новый NSArray содержит все данные, которые необходимо показать. Именно поэтому вы добавляете и удаляете из NSMutableArray, чтобы соответствовать новому.
  2. Вы не хотите потерять выбранное состояние строк в таблице.

Here're мои предложения

  1. Вместо того, чтобы опорожнение NSMutableArray и заселив его новый массив; почему бы не создать mutableCopy NSArray и установить это как новый NSMutableArray?
  2. Вместо того, чтобы беспокоиться о порядке пунктов (и, следовательно, выбранном номере строки); как создать копию выбранного объекта, и после создания нового NSMutableArray, как на шаге 1, найдите соответствующий объект в новом массиве и установите его как выбранную строку в таблице, используя свой новый индекс.
+0

Абизем ... Как и подход. По крайней мере, таким образом мне не нужно сравнивать каждый элемент в каждом массиве друг с другом. Даже если бы я взял направление «NSSet», sbooth предположил, что он все еще сравнивает. Этот подход означает, что мне нужно только установить выбранный индекс один раз и стрелять. Я реализую каждый и вижу, получаю ли я визуальную/разницу в производительности, используя один над другим. – Hooligancat

+0

Hooligancat ... также, если вы выполняете какое-либо сравнение равенства объектов, обязательно создайте метод 'isEqualTo:' для вашего класса объектов. Например, 'NSString' имеет метод' isEqualToString', который гарантирует, что строковые значения одинаковы, а не видят указатели 'NSString * '. – Abizern

+0

Хорошая точка Abizem. благодаря – Hooligancat

11

Вы можете использовать NSSet делать такого рода вещи легко (при условии, что ваши объекты человека уникальны):

NSSet *existingItems = [NSSet setWithArray:existingItemArray]; 
NSSet *newItems = /* Get the new items from the server */ 

// Determine which items were removed 
NSMutableSet *removedItems = [NSMutableSet setWithSet:existingItems]; 
[removedItems minusSet:newItems]; 

// Determine which items were added 
NSMutableSet *addedItems = [NSMutableSet setWithSet:newItems]; 
[addedItems minusSet:existingItems]; 

// Modify the original array 
[existingItemArray removeObjectsInArray:[removedItems allObjects]]; 
[existingItemArray addObjectsFromArray:[addedItems allObjects]]; 

Я был бы удивлен, если исполнение не порядочно, так как я уверен, реализация оптимизирована.

+0

Спасибо за предложение sbooth. Я не рассматривал использование NSSet, но этот подход имеет смысл в более эффективном подходе. Я могу потенциально иметь большой набор данных, поэтому все выгоды от эффективности, которые я получаю, помогут. – Hooligancat

+0

Хотя я не задавал этот вопрос, это ТОЧНО, что я пытался сделать в течение последних полутора дней, совершенно не повезло. Это элегантный фрагмент кода, и я сразу понял, что это то, что мне нужно. Спасибо тонну, это была находка в тот момент, когда я просто выбросил свой ноутбук из окна! : D –

+0

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

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