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的东西都可以处理它。
但是你不能只在NSNumber
and之间转换NSInteger
。NSNumber
里面有一个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
时,括号是可选的,但当您使用变量或常量时,它们是必需的。当然,如果你愿意,你仍然可以用罗嗦的方式来做,但现在已经没有什么意义了。