ios 如何用新对象替换给定索引处的 NSMutableArray 中的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3064122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to replace an object in an NSMutableArray at a given index with a new object
提问by user339076
I have an NSMutableArray
object (retained, synthesized as all) that is initiated just fine and I can easily add objects to it using the addObject:
method. But if I want to replace an object at a certain index with a new one in that NSMutableArray
, it doesn't work.
我有一个NSMutableArray
对象(保留,合成为所有),它启动得很好,我可以使用该addObject:
方法轻松地向其中添加对象。但是,如果我想用该索引中的新对象替换某个索引处的对象NSMutableArray
,则它不起作用。
For example:
例如:
ClassA.h
:
ClassA.h
:
@interface ClassA : NSObject {
NSMutableArray *list;
}
@property (nonatomic, copy, readwrite) NSMutableArray *list;
@end
ClassA.m
:
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
}
However, the change remains true only inside the method. from any other method, the
但是,更改仅在方法内部保持真实。从任何其他方法,
NSLog((NSString *)[self.list objectAtIndex:i]);
gives the same old value.
给出相同的旧值。
How can I actually get the old object replaced with the new one at a specific index so that the change can be noticed from within any other method as well.
我如何才能真正在特定索引处用新对象替换旧对象,以便也可以从任何其他方法中注意到更改。
I even modified the method like this, but the result is the same:
我什至像这样修改了方法,但结果是一样的:
-(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];
}
Please help out guys :)
请大家帮帮忙 :)
回答by Mário Carvalho
This does the trick:
这是诀窍:
[myMutableArray replaceObjectAtIndex:index withObject:newObject];
回答by walkytalky
OK, there are a few bits of confusion here.
好的,这里有一些混乱。
You don't need to take a mutableCopy
of a newly created NSMutableArray
to make it mutable. It's already mutable -- the clue is in the name. You only need to do that in the setter if you want the property to have copy
semantics (which you've set, and may have good reason for, of course). But you certainly wouldn't need to do it as shown in your updated updateTitle
code, and doing so leaks localList
.
您不需要mutableCopy
使用新创建的 aNSMutableArray
来使其可变。它已经是可变的——线索就在名字中。如果您希望属性具有copy
语义(您已经设置,当然可能有充分的理由),您只需要在 setter 中执行此操作。但是您当然不需要像更新后的updateTitle
代码中所示那样做,这样做会泄漏localList
。
Also, you're mixing together property access via self.list
and direct use of list
in the same method. This is not invalid, but it's bad practice, because it means whatever other stuff the accessor methods do is being randomly bypassed. It's common for properties like this to do everything through self
exceptin the accessors themselves, or in dealloc
, and possibly in init
(opinions seem to differ on this), where you would access the ivar directly.
此外,您将通过相同方法的属性访问self.list
和直接使用混合在一起list
。这不是无效的,但这是不好的做法,因为这意味着访问器方法所做的任何其他事情都会被随机绕过。这是常见的这样的特性,通过做的一切self
,除了在存取自己,或者dealloc
,也可能在init
(意见似乎在此不同),在那里你会直接访问伊娃。
Also, never call [self.list release]
-- the property accessor doesn't give its caller ownership. Doing this will end in tears, mark my words.
另外,永远不要调用[self.list release]
——属性访问器不给它的调用者所有权。这样做会以眼泪结束,记住我的话。
None of this answers the real question, which is why is your change disappearing. The original updateTitle
code does not explain this as far as I can see -- it should work. So I suspect that somewhere else you are calling self.list = theOriginalList
and hence undoing your change.
这些都没有回答真正的问题,这就是为什么您的更改消失了。updateTitle
就我所见,原始代码没有解释这一点——它应该可以工作。所以我怀疑你在其他地方打电话self.list = theOriginalList
,因此撤消了你的改变。
Update:
更新:
Just for the sake of argument, I'm going to post what I think the code you posted is probably meantto look like. I've preserved your use of a string to pass the index to updateTitle
, but I'd like to point out that doing it this way is wrong. It's a number, you should pass it as such. Even if the number comes from a text field or something, that's the caller's concern; the class interface should specify a number. Similarly the apparent change from 1-based to 0-based indexing. Please do not do this sort of thing implicitly, it is a recipe for weeping and gnashing of teeth.
为了讨论的缘故,我要发布什么,我认为你发布的代码很可能意味着样子。我保留了您使用字符串将索引传递给 的用法updateTitle
,但我想指出这样做是错误的。这是一个数字,你应该这样传递。即使号码来自文本字段或其他内容,这也是来电者的关注点;类接口应该指定一个数字。同样,从基于 1 到基于 0 的索引的明显变化。请不要含蓄地做这种事情,这是哭泣和咬牙切齿的秘诀。
ClassA.h:
类A.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:
班级A.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
This cleans up various issues, but note that updateTitle
is mostly the same. If you drop all this in and the change still doesn't survive, you are definitely resetting list
somewhere.
该清理的各种问题,但该说明updateTitle
是大致相同。如果您放弃所有这些,但更改仍然无法生存,那么您肯定是在list
某个地方重置。
回答by antonio081014
A more straight answer would be:
更直接的答案是:
self.list[i] = newTitle;
This just works like
这就像
[self.list replaceObjectAtIndex:i withObject:newTitle];
回答by gnasher729
Look at this line:
看看这一行:
@property (nonatomic, copy, readwrite) NSMutableArray *list;
The copymeans that whenever you access self.list, you don't get the "_list" instance variable of your object, but a copy of that list. If you write [self.list replaceObjectAtIndex... ] you replace an object in that copy of your list; the original _list is unchanged. Just use
该副本意味着,只要你访问self.list,你没有得到你的对象的“_list”实例变量,但该名单的副本。如果您编写 [self.list replaceObjectAtIndex... ] ,则您将替换该列表副本中的对象;原始 _list 不变。只需使用
@property (nonatomic, strong, readwrite) NSMutableArray *list;
And to avoid confusion, remove the "list" instance variable and the @synthesize statement, then use _list to access the instance variable.
并且为了避免混淆,删除“list”实例变量和@synthesize 语句,然后使用 _list 访问实例变量。
回答by Avijit Nagare
For Swift you could try:
对于 Swift,您可以尝试:
//if you have indexPath
self.readArray.removeAtIndex((indexPath?.row)!)
self.readArray.insert(tempDict, atIndex: (indexPath?.row)!)
//tempDict is NSDictionary object.
回答by Kavin Kumar Arumugam
Finally Got Some Perfect Code,
终于得到了一些完美的代码,
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)!
//Output Will Be Like
//输出会像
array = [
{
"name": "Kavin",
"Age": 25,
"is_married": "false"
},
{
"name": "Kumar",
"Age": 25,
"is_married": "false"
}
]