-1

我是obj c的新手。所以我有一个简单的问题。我有一个 NSInteger 值的矩阵。它被称为“curBoard”。我想用值“curStep”更新(x,y)坐标处的值。我有一个错误“算术类型为 void 的操作数......”

我究竟做错了什么 ?

[curBoard replaceObjectAtIndex:x withObject:(NSMutableArray *)[[curBoard objectAtIndex:x] replaceObjectAtIndex:y withObject:(NSInteger *)[NSNumber numberWithInt:curStep]]];

更新:

NSMutableArray *board; 
board = [NSMutableArray new]; 
for(NSInteger i = 0; i<boardSize; i++) { 
    NSMutableArray *row = [NSMutableArray new]; 

    for(NSInteger j = 0; j < boardSize; j++) 
        [row addObject:(NSInteger *)[NSNumber numberWithInt:0]]; 
        [board addObject:row]; 
    } 
4

2 回答 2

3

withObject:(NSInteger *)[NSNumber numberWithInt:curStep]]部分是导致问题的原因。如果你存储为 NSNumber 对象,你应该只使用:

... withObject:[NSNumber numberWithInt:curStep]]

编辑: 从上面发布的代码中,您应该将其添加为:

[row addObject:[NSNumber numberWithInt:0]]; 

NSInteger 不是指针类型,您应该使用 NSNumber 本身添加到数组中。

于 2013-03-08T20:14:42.703 回答
2

Objective-C 基本上只是一堆绑定到 C 的对象语法。整体效果就像将喷气背包绑在马上:有时这两个部分并不能很好地协同工作。在这种情况下,当你真的应该打开油门时,你会告诉马头晕目眩来试图跑得更快。

NSMutableArray是喷气背包的一部分——它是一个 Objective-C 对象,仅用于处理 Objective-C 对象的数组。但NSInteger它是马的一部分——它是一个原始的 C 整数类型,而不是一个真实的对象。*

我知道NSInteger它像一个类一样大写,并且有一个NS像类一样的前缀,但它实际上是 C 的产物。你可以自己确认这一点——在 Xcode 中输入 Cmd-O,然后在弹出的“快速打开”对话框中输入“NSInteger”,然后您将能够跳转到它的定义。在我当前的 Mac 项目中,这是typedef long NSInteger;; long是原始 C 类型之一。

NSNumber存在是为了弥合两者。它是一个专门设计用于在其中保存 C 数字类型的对象。既然NSNumber是一个对象,NSMutableArray其他Objective-C的东西都可以处理它。

但是你不能只在NSNumberand之间转换NSIntegerNSNumber里面有一个NSInteger,但这并不意味着它实际上就是一个NSInteger本身。如果你把一个三明治放在一个塑料袋里,你就不能吃这个袋子。

相反,您必须使用NSNumber'+numberWithInteger:方法来构造NSNumber,并-integerValue从中取出整数。(+numberWithInt:并且-intValue通常会起作用,但是对于非常大的值,它们的行为可能会有所不同,具体取决于您的应用程序是在 32 位还是 64 位处理器上运行。)实际上,现在您可以说[NSNumber numberWithInteger:foo]as @(foo),这要短得多。 **

所以当你添加一个数字时,你应该说:

[row addObject:@(0)];

当你以后想要那个号码回来时,你会想说:

n = [[row objectAtIndex:y] integerValue];

-replaceObjectAtIndex:withObject:错误是另一回事。-replaceObjectAtIndex:withObject:根本不返回任何内容,因此您不能将其用作参数。幸运的是,在这种情况下您不需要这样做。-replaceObjectAtIndex:withObject:不创建新数组;它改变了已经在里面的数组[curBoard objectAtIndex:x],所以你不需要做任何事情curBoard。相反,您可以只写:

[[curBoard objectAtIndex:x] replaceObjectAtIndex:y withObject:@(curStep)];

* 您实际使用NSInteger *的是 ,略有不同。这*意味着“指向”,NSInteger *指向原始整数的指针也是如此。这有点像NSNumber *,指向NSNumber对象的指针,因此编译器允许您对其进行强制转换。

请注意,转换指针不会转换指针另一端的数据;它只是使编译器以不同的方式解释相同的数据。如果您实际上尝试使用NSInteger *指针来获取数据,您将获得垃圾数据或(由于太大而无法容纳此余量)崩溃。

但是,在这种情况下,一旦绝地欺骗了编译器,让编译器认为 value 是指向 an 的指针NSInteger,你就会尝试将它传递给 to -addObject:-addObject:需要一个指向对象的指针,因此编译器不愿将指针传递给 an NSInteger

** 只要您使用的是 iOS 6 SDK Xcode 4.4 或更高版本,即使您实际在较旧的 iOS 上运行该应用程序,此语法也将有效。它还会自动+numberWithWhatever:为您使用正确的方法,因此您不必担心选择最好的方法。当您使用类似 的数字文字0时,括号是可选的,但当您使用变量或常量时,它们是必需的。当然,如果你愿意,你仍然可以用罗嗦的方式来做,但现在已经没有什么意义了。

于 2013-03-10T09:21:57.977 回答