我有一个包含MyClass
的各种实例的数组,它有四个属性:int id
,int valueA
,int valueB
和int valueC
。有时,我需要修改特定实例的属性(对于这个例子,假设它是id
等于5
的那个)。
目前我这样做:
MyClass *myClass = [[MyClass alloc] init];
for (int i = 0; i < [myMutableArray count]; i++)
{
myClass = [myMutableArray objectAtIndex:i];
if(myClass.id == 5)
{
myClass.valueA = 100;
myClass.valueB = 200;
myClass.valueC = 300;
[myMutableArray replaceObjectAtIndex:i withObject: myClass];
}
}
有没有更好的(我更犹豫要说更有效率)这样做的方式?
答案 0 :(得分:3)
如果您知道只有1个id
为5的实例,则只需在完成更新后在break;
语句的末尾添加if
。这将终止循环迭代并且可能是最有效的。
如果没有分析,你不应该过多担心运行时性能。
要编写更少的代码,您可以将for
写为:
for (MyClass *myClass in myMutableArray) {
如果您无论如何都需要经常访问单个项目,您可能希望更改为使用阵列存储。
另外,不要这样做:
MyClass *myClass = [[MyClass alloc] init];
因为你不必要地创建了一个你从未使用过的实例而且被扔掉了。
答案 1 :(得分:2)
在开始过度优化之前,您确定这是性能瓶颈吗?
另一种方法是将实例保留在NSMutableDictionary
,其中密钥为NSNumber
的{{1}}。然后,当您需要更新特定的一个时,您可以直接使用id
检索实例。这会将你的O(n)循环变成O(1)散列表查找[假设一个好的[myMutableDictionary objectForKey:@(someIntId)]
实现,或者在最坏的情况下它将是O(log n)。
答案 2 :(得分:2)
我看到了两种快速优化代码的方法。首先,你需要对新对象进行原始赋值以替换数组中的myClass实例 - 因为它是一个指针,你实际上直接操作数组中的对象。其次,如果您使用增量器保留当前的for循环,则不需要原始分配的MyClass。你不需要对它进行alloc和init,因为你只需要一个指针。但是,您可以使用for循环而不是递增for循环并直接循环遍历数组。
最终代码:
for (MyClass *myClass in myMutableArray)
{
if(myClass.id == 5)
{
myClass.valueA = 100;
myClass.valueB = 200;
myClass.valueC = 300;
}
}
答案 3 :(得分:1)
根据任何标准获取数组中特定成员的简单方法虽然冗长,但使用indexOfObjectPassingTest:
并结合objectAtIndex:
MyClass * theInstanceIWant;
theInstanceIWant = [myArray objectAtIndex:[dates indexOfObjectPassingTest:^BOOL (id obj, NSUInteger idx, BOOL *stop) {
return ([obj id] == 5);
}];
theInstanceIWant.valueA = 100;
theInstanceIWant.valueB = 200;
theInstanceIWant.valueC = 300;
无需使用replaceObjectAtIndex:withObject:
- 名称theInstanceIWant
指的是数组中的实际对象,您可以在数组中保留其属性时更改其属性。
(使用NSArray
上的类别方法会更加愉快。)
- (id)WSSObjectPassingTest:(BOOL (^)(id obj, NSInteger idx, BOOL *stop))test
{
NSUInteger testedIndex = [self indexOfObjectPassingTest:test];
return [self objectAtIndex:testedIndex];
}
答案 4 :(得分:0)
首先,你永远不想在Objective-C中命名一个变量id
。id
表示指向任何类型的指针,它是一个保留的关键字。
更好/更有效的方法称为快速枚举。快速枚举是迭代列表/数组/集中每个项的特殊方法。代码如下所示:
for (MyClass *iteratorObject in myMutableArray) {
if (iteratorObject.id == 5) {
//do what you want with that specific object
//insert your modified object back into mutable array
}
虽然这是最简单的方法,但你违反了一条规则。在阵列上执行快速枚举时,永远不应该编辑/添加/删除对象。我的解决方案是简单地调用返回immutableArray的[myMutableArray copy]
,然后遍历它。