1

副标题:为什么这段代码有效?它似乎允许通过某种强制NSNumber与类型进行比较。NSString我正在尝试将 a 中的选择UISegmentedControl与先前存储的值进行比较。

- (IBAction)minSegmentedControlChanged:(id)sender // MINIMUM value
{
UISegmentedControl *s1 = (UISegmentedControl *)sender;

NSMutableArray *pD = [[GameData gameData].curData valueForKey:@"persData"];

// Must make sure max >= min

NSNumber *currMax = [pD objectAtIndex:1];
NSLog(@"%@", [currMax class]); // __NSCFString ?!

int ss1 = s1.selectedSegmentIndex;
NSNumber *SS1 = [NSNumber numberWithInt:ss1 + 2];

if (SS1 >= currMax) SS1 = currMax;

NSLog(@"%@", SS1); // Answer is correct, appears to be an integer
NSLog(@"%@", [SS1 class]); // __NSCFString ?!

[pD replaceObjectAtIndex:0
              withObject:SS1];
[[GameData gameData].curData setObject:pD
                                forKey:@"persData"];
NSLog(@"%@", [[GameData gameData].curData valueForKey:@"persData"]);

}

我特别想问:

NSNumber *currMax = [pD objectAtIndex:1];
NSLog(@"%@", [currMax class]); // __NSCFString ?!

这似乎返回一个数字的字符串。 [[GameData gameData].curData valueForKey:@"persData"];初始化如下:

         _persData = [[NSMutableArray alloc] initWithObjects:@"2", @"8", @"TWL", @"0", @"0", nil];

这是元素 1 处的字符串。那么为什么我可以向它询问 an NSNumber,它报告它实际上是__NSCFString我可以在其上进行算术比较的 a 呢?我只在objective-c工作了几个月,但这似乎很奇怪。

4

2 回答 2

8

好的,让我们一步一步来。

首先,其中的所有元素_persData都是字符串。时期。NSString是一个类集群,因此您查询的各种实例的具体类可能看起来很奇怪,但这是为了支持免费桥接和其他与本讨论无关的魔法。

NSNumber *currMax = [pD objectAtIndex:1];

此行不正确。你可能认为发生了某种强制,但实际上你只是将 an 分配NSString *NSNumber *. 这是错误的,并且会在您方便的时候尽早爆炸。碰巧objectAtIndex:返回一个id,它被剥离了类型信息,因此编译器相信您将其存储在正确类型的指针中,但在您尝试向它发送消息之前不会强制执行。

if (SS1 >= currMax) SS1 = currMax;

这是一个非常巧妙的比较。SS1肯定是一个NSNumber,但是currMax是一个NSString。但我们不是在比较这些对象的值。为此,我们将使用该compare:方法。相反,我们将它们作为指针进行比较,只查看它们在内存中的地址。由于一些意外的实现,SS1似乎总是驻留在比currMax.

如果上述所有条件都为真,那么在执行上述行之后,SS1它始终是类型,这就解释了为什么这行:NSString

NSLog(@"%@", [SS1 class]);

始终表示它SS1是一个字符串。

于 2012-06-26T01:43:40.727 回答
2

您实际上初始化了NSMutableArraywith NSString,而不是 number 。

NSMutableArray当你从with中取出对象时,objectAtIndex函数的返回类型是id,它会盲目地转换为NSNumber,而实际的对象是NSString

似乎该SS1 >= currMax语句是在比较对象的地址而不是它们的值。

您可以使用以下代码片段对其进行测试:

NSNumber *a = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *b = [[NSNumber alloc] initWithUnsignedInt: 3];

NSNumber *c = [[NSNumber alloc] initWithUnsignedInt: 34];
NSNumber *d = [[NSNumber alloc] initWithUnsignedInt: 234];

NSLog(@"%p %p %p %p %d %d", a, b, c, d, a >= b, c >= d);
于 2012-06-26T01:34:57.580 回答