Простой NSArray - переместить объект на передний план NSArray

Простой вопрос для NSarray. У меня есть объекты, хранящиеся в NSMuteableArray. [объект1, объект2, объект3]

Если объект выбран, я хочу вывести его на передний план массива. т.е. если выбран obj3, то:

[объект3, объект1, объект2]

Будет ли нижеприведенное работать или дублировать obj3? Кроме того, можно ли сделать это потокобезопасным?

[myMutableArray insertObject:obj3 atIndex:0];

person DaynaJuliana    schedule 10.01.2015    source источник
comment
Если вы вставите obj3 впереди, это не будет иметь ничего общего с obj2. После того, как вы запустите эту строку, ваш массив будет [obj3, obj1, obj2, obj3].   -  person Dan Watkins    schedule 10.01.2015
comment
@DanWatkins извините, я отредактировал ? и пропустил эту часть. Могу ли я переместить его на передний план БЕЗ повторного добавления объекта. И сохраняя оставшийся порядок нетронутым   -  person DaynaJuliana    schedule 10.01.2015
comment
убери его, а потом добавь впереди   -  person nielsbot    schedule 10.01.2015
comment
@nielsbot спасибо! Я застрял между изменением своего свойства с NSMuteable Array на NSArray и манипулированием им с помощью метода muteableCopy. Это кажется проще и безопаснее для потоков по сравнению с синхронизацией свойства.   -  person DaynaJuliana    schedule 10.01.2015
comment
Вам все равно придется обернуть код в @synchronized (или использовать функцию GCD), если вы хотите быть потокобезопасным. Кто-то может вызвать ваш метод, ваш вызов может быть прерван, и может произойти другой вызов вашего метода. Ваш массив будет искажен.   -  person nielsbot    schedule 10.01.2015
comment
@nielsbot от GCD, будет ли работать dispatch_barrier_async? В настоящее время я удаляю объекты из основной очереди, добавляя объекты в async_thread через AFNetworking (загружая объекты и добавляя их один за другим). Я переключаю порядок в совершенно другой теме. Должен ли я использовать dispatch_barrier_async ? Ни одна из этих операций не требует много времени, поэтому блокировка не должна быть большой проблемой. Я могу опубликовать полное редактирование, если это необходимо   -  person DaynaJuliana    schedule 10.01.2015
comment
обернув его в @synchronized(self), все должно быть в порядке.   -  person nielsbot    schedule 10.01.2015
comment
но вам точно нужна синхронизация исходя из вашего описания   -  person nielsbot    schedule 10.01.2015


Ответы (2)


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

NSMutableArray *array = ... // array with objects
NSInteger index = ... // index of object to move to the front
id obj = array[index];
[array removeObjectAtIndex:index];
[array insertObject:obj atIndex:0];
person rmaddy    schedule 10.01.2015
comment
Хороший ответ. (проголосовал). Сначала я не заметил, что ОП хотел сдвинуть все остальные элементы вниз, а не поменять местами рассматриваемый элемент с первым элементом, и вместо этого собирался предложить exchangeObjectAtIndex:withObjectAtIndex:, но это не то, чего хочет ОП. - person Duncan C; 10.01.2015
comment
@rmaddy, после пересмотра этого - есть ли способ сделать это с помощью NSPredicate, чтобы я не мог выполнить это на NSArray и сохранить потокобезопасность? - person DaynaJuliana; 08.02.2015

Ваш код вставит еще одну ссылку на obj3 в начале массива (т. е. теперь массив будет содержать 4 элемента), но на самом деле он не будет дублировать объект.

Вам нужно использовать exchangeObjectAtIndex:withObjectAtIndex -

[myMutableArray exchangeObjectAtIndex:0 withObjectAtIndex:selectedIndex]

где selectedIndex — индекс выбранного объекта.

NSMutableArray не является потокобезопасным, поэтому вам нужно будет обернуть @synchronizsed(myMutableArray) доступ к этому массиву, если вы потенциально изменяете его из нескольких потоков или изменяете его, пока другой поток повторяет его.

Если вы хотите сохранить порядок массива за пределами первого элемента, вам нужно будет выполнить отдельную операцию удаления и вставки -

id someObject=myMutableArray[selectedIndex];
[myMutableArray removeObjectAtIndex:selectedIndex];
[myMutableArray insertObject:someObject atIndex:0]; 
person Paulw11    schedule 10.01.2015
comment
На самом деле это не сохраняет порядок, как сказал @rmaddy - person DaynaJuliana; 10.01.2015
comment
Вы могли бы, но вам все равно нужно @synchronise операцию копирования - person Paulw11; 10.01.2015
comment
Это не дает желаемых результатов. Начиная с 1,2,3 это дает 3,2,1, а не 3.1.2. - person rmaddy; 10.01.2015