如何使用新对象替换给定索引处的NSMutableArray中的对象

时间:2010-06-17 17:39:58

标签: ios objective-c nsarray

我有一个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];
}

请帮帮忙:)

6 个答案:

答案 0 :(得分:125)

这就是诀窍:

[myMutableArray replaceObjectAtIndex:index withObject:newObject];

答案 1 :(得分:8)

好的,这里有一些混乱。

您不需要使用mutableCopy新创建的NSMutableArray来使其变为可变。它已经是可变的 - 线索就在名字中。如果你希望属性具有copy语义(你已经设置了,当然可能有充分的理由),你只需要在setter中这样做。但您肯定不需要按照更新的updateTitle代码中的说明执行此操作,并且这样做会泄漏localList

此外,您通过self.list将属性访问权混合在一起,并在同一方法中直接使用list。这不是无效的,但这是不好的做法,因为它意味着访问者方法所做的任何其他事情都被随机绕过。对于这样的属性来说,通过self 除了在访问者本身或dealloc中,以及可能在init中执行所有操作(意见似乎有所不同)这个),你可以直接访问ivar。

此外,永远不要致电[self.list release] - 财产访问者不会给予其来电者所有权。这样做会以泪水结束,标记我的话。

这些都没有回答真正的问题,这就是为什么你的改变正在消失。就我所见,原始的updateTitle代码并没有解释这一点 - 它应该可行。所以我怀疑你正在调用self.list = theOriginalList的其他地方,从而撤消你的改变。

<强>更新

仅仅为了争论,我将发布我认为您发布的代码可能意味着的内容。我保留了使用字符串将索引传递给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

答案 2 :(得分:6)

更直接的答案是:

self.list[i] = newTitle;

这就像

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

答案 3 :(得分:0)

看看这一行:

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

副本表示无论何时访问self.list,您都无法获得&#34; _list&#34;对象的实例变量,但该列表的副本。如果您编写[self.list replaceObjectAtIndex ...],则替换列表副本中的对象;原始的_list没有变化。只需使用

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

为避免混淆,请删除&#34;列表&#34;实例变量和@synthesize语句,然后使用_list访问实例变量。

答案 4 :(得分:0)

对于Swift你可以尝试:

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

答案 5 :(得分:0)

终于有了一些完美的代码,

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"
  }
]