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

Как заменить объект в NSMutableArray на данный индекс новым объектом

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

Например:

ClassA.h:

@interface ClassA : NSObject {
    NSMutableArray *list;
}

@property (nonatomic, copy, readwrite) NSMutableArray *list;

@end

ClassA.m:

#import "ClassA.h"

@implementation ClassA

@synthesize list;

- (id)init 
{
    [super init];
    NSMutableArray *localList = [[NSMutableArray alloc] init];
    self.list = localList;
    [localList release];
    //Add initial data
    [list addObject:@"Hello "];
    [list addObject:@"World"];
}


// Custom set accessor to ensure the new list is mutable
- (void)setList:(NSMutableArray *)newList 
{
    if (list != newList) 
    {
        [list release];
        list = [newList mutableCopy];
    }
}

-(void)updateTitle:(NSString *)newTitle:(NSString *)theIndex
{
    int i = [theIndex intValue]-1;
    [self.list replaceObjectAtIndex:i withObject:newTitle];
    NSLog((NSString *)[self.list objectAtIndex:i]);  // gives the correct output
}

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

NSLog((NSString *)[self.list objectAtIndex:i]);

дает то же старое значение.

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

Я даже модифицировал такой метод, но результат тот же:

-(void)updateTitle:(NSString *)newTitle:(NSString *)theIndex
{
    int i = [theIndex intValue]-1;

    NSMutableArray *localList = [[NSMutableArray alloc] init];
    localList = [localList mutableCopy];
    for(int j = 0; j < [list count]; j++)
    {
        if(j == i)
        {
            [localList addObject:newTitle];
            NSLog(@"j == 1");
            NSLog([NSString stringWithFormat:@"%d", j]);
        }
        else
        {
            [localList addObject:(NSString *)[self.list objectAtIndex:j]];
        }
    }
    [self.list release];
    //self.list = [localList mutableCopy];
    [self setList:localList];
    [localList release];
}

Пожалуйста, помогите парням:)

4b9b3361

Ответ 1

Это трюк:

[myMutableArray replaceObjectAtIndex:index withObject:newObject];

Ответ 2

ОК, здесь есть несколько путаниц.

Вам не нужно брать mutableCopy вновь созданного NSMutableArray, чтобы сделать его изменяемым. Он уже изменен - ​​ключ в названии. Вам нужно сделать это только в установщике, если вы хотите, чтобы свойство имело семантику copy (которую вы установили, и, возможно, для этого есть веская причина). Но вам, конечно, не нужно будет делать это, как показано в обновленном коде updateTitle, и делает это утечки localList.

Кроме того, вы смешиваете доступ к свойствам через self.list и прямое использование list в том же методе. Это не является недопустимым, но это плохая практика, потому что это означает, что любой другой материал, который используют методы доступа, случайно исключается. Обычно для таких свойств, как это, делать все через self, за исключением самих аксессуаров или в dealloc и, возможно, в init (мнения, по-видимому, отличаются от этого), где вы должны получить доступ к ivar напрямую.

Кроме того, никогда не вызывайте [self.list release] - аксессуар свойства не дает права собственности на вызывающего абонента. Выполнение этого закончится слезами, отметьте мои слова.

Ничто из этого не отвечает на реальный вопрос, поэтому ваши изменения исчезают. Оригинальный код updateTitle не объясняет это, насколько я вижу - он должен работать. Поэтому я подозреваю, что в другом месте вы вызываете self.list = theOriginalList и, следовательно, отменяете свое изменение.

Update:

Просто для аргументации, я собираюсь опубликовать то, что, по-моему, означает, что код, который вы опубликовали, должен выглядеть. Я сохранил ваше использование строки, чтобы передать индекс в updateTitle, но я хотел бы указать, что делать это так неправильно. Это число, вы должны передать его как таковое. Даже если номер поступает из текстового поля или чего-то еще, что вызывает вызывающий вызов; интерфейс класса должен указывать число. Точно так же кажущееся изменение индексации от 1 до 0. Пожалуйста, не делайте этого неявно, это рецепт для плача и скрежещения зубов.

ClassA.h:

#import <Cocoa/Cocoa.h>
@interface ClassA : NSObject
{
    NSMutableArray* list;
}
- (void) setList:(NSMutableArray*)newList;
- (void) updateTitle:(NSString*)newTitle forIndex:(NSString*)theIndex;
@property (nonatomic, copy, readwrite) NSMutableArray* list;
@end

ClassA.m:

#import "ClassA.h"

@implementation ClassA
@synthesize list;

- (id) init
{
    if ( self = [super init] )
    {
        list = [[NSMutableArray alloc] init];
        [list addObject:@"Hello "];
        [list addObject:@"World"];
    }
    return self;
}

- (void) setList:(NSMutableArray*) newList
{
    if ( list != newList )
    {
        [list release];
        list = [newList mutableCopy];
    }
}

- (void) updateTitle:(NSString*)newTitle forIndex:(NSString*)theIndex
{
    int i = [theIndex intValue] - 1;
    [self.list replaceObjectAtIndex:i withObject:newTitle];
}

- (void) dealloc
{
    [list release];
    [super dealloc];
}

@end

Это устраняет различные проблемы, но обратите внимание, что updateTitle в основном то же самое. Если вы отбросите все это, и изменение все равно не сохранится, вы определенно сбросите list где-нибудь.

Ответ 3

Более прямой ответ:

self.list[i] = newTitle;

Это просто работает как

[self.list replaceObjectAtIndex:i withObject:newTitle];

Ответ 4

Посмотрите на эту строку:

@property (nonatomic, copy, readwrite) NSMutableArray *list;

копия означает, что всякий раз, когда вы получаете доступ к self.list, вы не получаете переменную экземпляра "_list" вашего объекта, а копию этого списка. Если вы пишете [self.list replaceObjectAtIndex...], вы заменяете объект в этой копии вашего списка; исходный _лист не изменился. Просто используйте

@property (nonatomic, strong, readwrite) NSMutableArray *list;

Чтобы избежать путаницы, удалите переменную экземпляра "list" и инструкцию @synthesize, а затем используйте _list для доступа к переменной экземпляра.

Ответ 5

Для Swift вы можете попробовать:

 //if you have indexPath
   self.readArray.removeAtIndex((indexPath?.row)!)
   self.readArray.insert(tempDict, atIndex: (indexPath?.row)!)
 //tempDict is NSDictionary object.

Ответ 6

Наконец, появился совершенный код,

let DuplicateArray: NSArray = array
let DuplicateMutableArray: NSMutableArray = []
DuplicateMutableArray.addObjectsFromArray(DuplicateArray as [AnyObject])
var dic = (DuplicateMutableArray[0] as! [NSObject : AnyObject])
dic["is_married"] = "false"
DuplicateMutableArray[self.SelectedIndexPath] = dic
array = []
array = (DuplicateMutableArray.copy() as? NSArray)!

//Результат будет

array =  [
  {
    "name": "Kavin",
    "Age": 25,
    "is_married": "false"
  },
  {
    "name": "Kumar",
    "Age": 25,
    "is_married": "false"
  }
]