如何在NSArray中修改存储为NSValue的CGRect?

Osc*_*mez 1 iphone nsarray

我正在使用以下行创建一个带有CGRects的NSArray:

[self setMyArray:[NSArray arrayWithObjects:[NSValue valueWithCGRect:CGRectMake(x,y,z,a)], [NSValue valueWithCGRect:CGRectMake(x,y,z,a)], nil]]
Run Code Online (Sandbox Code Playgroud)

然后,我经常尝试更新数组中的CGrects,如下所示:

for (NSValue *bound in myArray)
  {
   CGRect myRect = [bound CGRectValue];
   myRect.origin.y += 2;
  }
Run Code Online (Sandbox Code Playgroud)

但是这不起作用,当循环再次运行时,原点仍然相同.我假设这与NSValue包装器有关?,我该怎么做才能在数组中实际更新该值?谢谢.

-Oscar

Ole*_*ann 5

NSValue对象是不可变的,因此您无法做任何事情.您应该使用可变数组并将现有对象替换为包含新rect的新NSValue实例.


Ste*_*ntz 5

正如其他人提到的,NSValue实例不是可变的,所以你必须重新创建它们,然后将它们替换为NSMutableArray.

另一种选择是使用更多"经典"C内存管理(malloc/free)并以这种方式管理您的阵列.走那条路是没有错的.您必须更加小心,因为它不具有Objective-C/Foundation API的高级别.

// Create an array to hold 100 rectangles
CGRect* rectangles = (CGRect*) malloc(100 * sizeof(CGRect));

// Change the rectangle at index 2 (remember arrays are 0 based, so this is the 3rd)
CGRect* rect = &rectangles[2];
rect->size.width /= 2.0;

// Shortcut for accessing rectangles
rectangles[2].size.width = 100.0;

// Get rid of the array
free(rectangles);
Run Code Online (Sandbox Code Playgroud)

如果你在游戏中工作,也可能更快.