【问题标题】:Crazy problems with data types and arrays in Objective-CObjective-C 中的数据类型和数组的疯狂问题
【发布时间】:2014-09-23 12:26:42
【问题描述】:

我有一个存储在全局 int 变量中的分数。我想在每次游戏结束时将每个新分数添加到数组中。因此,代码如下所示:

@implementation MainScene{
   NSInteger *_scorevalue;
    NSMutableArray *_scores;
}

在 didLoad 方法中:

  [[NSUserDefaults standardUserDefaults] setObject:_scores forKey:@"gameScores"];

游戏过程中_scorevalue的值会发生变化(物体碰撞时,但没关系):

 _scorevalue=_scorevalue + 10;

游戏结束时:

[_scores addObject:_scorevalue]; 

Xcode 在这里显示了一个问题:“非 Objective-C 指针类型 int 到 id 类型参数的隐式转换”。

我尝试将 _scorevalue 类型更改为在实现中浮动(结果相同)。但是当我改用 NSNumber 时,[_scores addObject:_scorevalue]; 附近的问题消失了,_scorevalue=_scorevalue + 10; 附近出现了新问题:“指向接口 NSNumber 的指针的算术,这对于该架构和平台来说不是一个恒定的大小”。

你能给我解释一下吗?如何解决这一切?!

编辑 Rob 的答案:

实施:

NSInteger _scorevalue;

游戏结束时:

  NSNumber *_scoreNumber= [NSNumber numberWithInteger:@(_scorevalue)]; // Xcode shows warning:
// "Incompatible pointer to integer conversion sending NSNumber to parameter of type NSInteger(aka // int)"
        [_scores addObject:_scoreNumber];

编辑:nburk 显示更好(没有警告):

[_scores addObject:@(_scorevalue];)

【问题讨论】:

    标签: objective-c pointers nsmutablearray int nsarray


    【解决方案1】:
    NSInteger *_scorevalue;
    

    这是一个指向整数的指针。你的意思是只有一个整数。删除*。

    您也不能将整数添加到NSMutableArray。您需要将其装箱为NSNumber,例如@(_scorevalue)。


    请注意,这不是实现属性的好方法。使用@property:

    @interface MainScene ()
    @property(nonatomic, readwrite, strong) NSMutableArray *scores;
    @property(nonatomic, readwrite, assign) NSInteger score;
    @end
    

    养成通过它们的属性访问它们的习惯:self.scores 和 self.score。在 ObjC 中直接访问 ivar 并不是一个好主意,即使使用 ARC。

    【讨论】:

    • 请检查已编辑问题中的代码。你能解释一下为什么更好地使用属性,或者你有一些很好的链接供初学者阅读吗?
    • ObjC 有许多特性(例如 KVO 和延迟初始化),如果您绕过访问器(这可能会导致非常细微的错误),这些特性就会被破坏。除非在 init、访问器中或对它有特定要求时(通常与 C 或 C++ 接口相关),否则不应使用原始 ivars。正如 Apple 所说,“对象使用访问器方法或点语法访问其自己的属性是最佳实践。”有关更多信息,我强烈建议您阅读所有内容:developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…
    【解决方案2】:

    具体而言,您可以绕过错误将定义或实例变量更改为:

    @implementation MainScene{
       NSInteger _scorevalue;
       NSMutableArray *_scores;
    }
    

    并将数组添加到:

    [_scores addObject:@(_scorevalue];)

    请注意,这样做会将_scoreValue 存储为NSNumber 类型的对象,因此当您检索它时,您需要在该对象上调用integerValue,类似于:

    NSNumber *theScoreAsNumber = _scores[0];
    NSInteger theScoreAsInteger = [theScoreAsNumber integerValue];
    

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多