我是对象中的新手。所以我有一个简单的问题。 我有一个NSInteger值的矩阵。它被称为“curBoard”。我想用值“curStep”更新(x,y)坐标处的值。我有一个恐怖的“操作数类型为void where arithmetic ...”
我做错了什么?
[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];
}
答案 0 :(得分:3)
此withObject:(NSInteger *)[NSNumber numberWithInt:curStep]]
部分是造成问题的原因。如果要存储为NSNumber对象,则应使用:
... withObject:[NSNumber numberWithInt:curStep]]
修改强> 从上面发布的代码中,您应该将其添加为:
[row addObject:[NSNumber numberWithInt:0]];
NSInteger不是指针类型,您应该使用NSNumber本身添加到数组。
答案 1 :(得分:2)
Objective-C基本上只是一堆绑在C上的对象语法。整体效果就像是将一个喷气背包捆绑在马上:有时两个部分并没有真正协同工作。在这种情况下,当你应该真正打开油门时,你会试图通过告诉马眩晕来加快速度。
NSMutableArray
是jetpack的一部分 - 它是一个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事物可以处理它。
但你不能只在NSNumber
和NSInteger
之间施放。 NSNumber
在其中包含NSInteger
,但这并不意味着它本身就是NSInteger
。如果你把三明治放在塑料袋里,你就不能吃掉它。
相反,您必须使用NSNumber
的{{1}}方法来构建+numberWithInteger:
,并使用NSNumber
来获取整数。 (-integerValue
和+numberWithInt:
通常会有效,但根据您的应用是在32位还是64位处理器上运行,它们可能会因非常大的值而表现不同。)实际上,现在您可以请将-intValue
改为[NSNumber numberWithInteger:foo]
,这要短得多。**
所以当你添加一个数字时,你应该说:
@(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
指针来获取数据,那么您将获得垃圾数据或(因为太大而无法适应此边距的原因)崩溃。
但是,在这种情况下,一旦你让Jedi哄骗编译器认为值是指向NSInteger *
的指针,你就会尝试将其传递给NSInteger
。 -addObject:
需要一个指向对象的指针,因此编译器会将指针传递给-addObject:
。
**只要你使用 iOS 6 SDK Xcode 4.4或更高版本,即使你真的在较旧的iOS上运行应用程序,这种语法也会有效。它还会自动为您使用正确的NSInteger
方法,因此您无需担心选择最佳方法。当您使用像+numberWithWhatever:
这样的数字文字时,括号是可选的,但在使用变量或常量时它们是必需的。当然,如果你愿意,你仍然可以采用罗嗦的方式,但现在没有什么意义。