Objective-C正确设置Instance Variables语法

时间:2014-02-12 21:54:22

标签: objective-c syntax instance-variables

嗨,首先让我说谢谢你帮助我解决这个问题。我目前正在尝试学习Objective-C。我第一次开始在AP计算机科学(在我的高中教授)游戏中学习Java ...但是,我一直在尝试从Java扩展到Objective-C。大多数情况下,我可以搞乱制作iPhone应用程序。我已经阅读了不少指南,但我一直被卡住和不堪重负,所以我只是停止我正在做的事情并回到java ..然而,这次我决心克服这个小问题!所有回复都表示赞赏!所以这是我将在我的Sprite 2-D游戏测试项目中使用的VectorObject类。但是,我在使用一般的Objective-C语法时遇到了麻烦。我尝试了几种不同的东西,但似乎无法使它工作,我只是得到错误。

TLDR:这是我的类,我正在尝试使用所需的实例变量创建一个VectorObject,但我不知道如何正确地将参数添加到实例变量。

#import <Foundation/Foundation.h>

@interface VectorObject : NSObject

@property(nonatomic) BOOL alive;
@property(nonatomic) NSDecimal *x;
@property(nonatomic) NSDecimal *y;
@property(nonatomic) NSDecimal *velX;
@property(nonatomic) NSDecimal *velY;
@property(nonatomic) NSDecimal *maxVelX;
@property(nonatomic) NSDecimal *maxVelY;
@property(nonatomic) NSDecimal *moveAngle;
@property(nonatomic) NSNumber *faceAngle;

- (void)incX:(NSDecimal *) x;
- (void)incY:(NSDecimal *) y;
- (void)incVelY:(NSDecimal *) velY;
- (void)incVelX:(NSDecimal *) velX;
- (void)incFaceAngle:(NSDecimal *) faceAngle;
- (void)incMoveAngle:(NSDecimal *) moveAngle;
+ (NSDecimal)calcAngleMoveX:(NSDecimal *) ang;
+ (NSDecimal)calcAngleMoveY:(NSDecimal *) ang;

@end

现在是我的实施课程。

#import "VectorObject.h"

@implementation VectorObject

@synthesize alive;
@synthesize x, y;
@synthesize velX, velY;
@synthesize maxVelX, maxVelY;
@synthesize moveAngle, faceAngle;

-(void)incY:(NSDecimal *)y
{

}
-(void)incX:(NSDecimal *)x
{

}
-(void)incVelY:(NSDecimal *)velY
{

}
-(void)incVelX:(NSDecimal *)velX
{

}
-(void)incFaceAngle:(NSDecimal *)faceAngle
{

}
-(void)incMoveAngle:(NSDecimal *)moveAngle
{

}
+(NSDecimal) calcAngleMoveX:(NSDecimal *)ang
{

}
+(NSDecimal) calcAngleMoveY:(NSDecimal *)ang
{

}

@end

所以我在Java中知道我可以简单地定义incX(double x)

public void incX(double x)
{
    this.x += x;
}

但我不确定如何在Objective-C中执行此操作?

-(void)incX:(NSDecimal *)x
{
     self.x += [NSDecimal *] x;
}

编辑:所有语法提示,一般实施等都受到赞赏并将投入使用!

3 个答案:

答案 0 :(得分:3)

在Java中,您使用了double - 这是原始值类型,而不是对象。标准数学运算可与double

一起使用

在Objective-C中,您使用了NSDecimal * - 这是一个指针类型,它也不是对象但也许您打算使用NSDecimalNUmber *。您必须使用类型提供的函数(NSDecimal)或方法(NSDecimalNumber),不能使用标准数学运算。

为什么不在Objective-C中使用double,它是标准的原始值类型。还有float精度较低。

答案 1 :(得分:1)

self.x += [NSDecimal *] x;

不,那不太对劲。这样做:

self.x = [self.x decimalNumberByAdding:x];

使用NSDecimalNumber时,请查看class reference以查看可以使用的方法,并记住NSDecimalNumber对象是不可变的,因此对它们的操作会返回新对象。

一个小问题:如果您为要添加的号码使用不同的名称,可能会有点混乱,例如:

-(void)incX:(NSDecimalNumber *)increment
{
     self.x = [self.x decimalNumberByAdding:increment];
}

答案 2 :(得分:-1)

您需要知道的一件事是iOS和OS X包装基类型并提供帮助您使用它们的功能。他们已经完成了这个b / c包装器给了一个抽象,远离硬件和芯片依赖于大小等基础类型,如float和double。所以希望这有助于您了解在Objective-C中使用iOS和OS X上的数字的选项。

NSDecimal结构是一个基础&#39;输入iOS和OS X Objective-C。他们是&#39; C&#39;结构。下面的文档链接更详细。还有一个NSDecimalNumber类,您可以从Objective-C代码中使用它。它的方法将NSDecimals作为参数。您可以使用NSDecimal或NSDecimalNumber。如果想在&#39; C&#39;工作,请使用NSDecimal。功能/程序水平。如果要使用对象并使用Objective-C消息语法级别,请使用NSDecimalNumber。请注意,您也可以同时使用这两个级别。

在我给出答案之前,下面是苹果文档的链接。

在iOS和OS X上使用Numbers的非常重要的文档

数字和其他值的介绍

https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/NumbersandValues/NumbersandValues.html#//apple_ref/doc/uid/10000038i

“使用十进制数字”部分&#39;是你关心的主要人物,但是从那以后

的Structs

NSDecimal

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html

这里使用NSDecimal结构进行数学运算的函数。

基础功能

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/doc/uid/20000055-BCIHCEFJ

物件

NSDecimalNumber

https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/nsdecimalnumber_class/reference/reference.html


不改变班级的解决方案

您的类将属性定义为NSDecimal,并传入NSDecimal arg。所以你可以解决两个基本方法。一个人使用&#39; C&#39;等级&#39;基金会&#39;诸如 NSDecimalAdd 之类的函数以及使用类NSDecimalNumber的其他函数。第二个是我要展示的内容。

incX:方法的代码如下所示:

// I changed your method name to make it 
// more like other Objective-C code that read more like a sentence
// I changed the argument name because your really adding the new value to x
-(void)incrementXBy:(NSDecimal*)incrementValue
{
  // _x is what the @property annotation creates for us for the property x

  // Create a NSDecimalNumber object from our internal NSDecimal struct in _x
  NSDecimalNumber currentXAsDN = [NSDecimalNumber decimalNumberWithDecimal: _x];

  // Create a NSDecimalNumber object from the argument NSDecimal passed to us
  NSDecimalNumber incrementValueAsDN = [NSDecimalNumber decimalNumberWithDecimal: incrementValue];

  // Now we can add the two objects 
  NSDecimalNumber newX = [currentXAsDN decimalNumberByAdding: incrementValueAsDN];

  // Since we have our property 'x' defined as a NSDecimal, get that struct out of our newX object and set our 'x' property to it.
  _x = [newX decimalValue];

}

这是一个基于你如何声明你的类的解决方案。

要在不创建NSDecimalNumber对象的情况下执行此操作,请使用直接在NSDecimal结构上工作的函数NSDecimalAdd。为此,您需要确定如何使用RoundingMode以及NSDecimalAdd()的函数文档中详细说明的内容。我猜你想要继续使用NSDecimal,因为它是一个结构,你需要性能,但如果它不是那么大的交易,你可以改变你的属性来使用NSDecimalNumber对象。这将简化上面的代码示例,使其不需要从NSDecimal结构创建NSDecimalNumber对象。

解决此问题的另一种方法是使用&#39; C&#39;来声明您的属性。的加倍即可。如果您这样做,您的代码将看起来像正常&#39; C&#39;码。但是要非常清楚,如果你这样做,那么你正在讨论框架包装及其背后的原因。

更好的解决方案恕我直言

我改变你的类以使属性使用NSDecimalNumber并且还将NSDecimalNumber的实例传递给你的方法。如果你这样做,那么方法将如下所示:

-(void)incrementXBy:(NSDecimalNumber*)incrementValue
{

  // Now we can add the two objects 
  _x = [currentXAsDN decimalNumberByAdding: incrementValueAsDN];

}

我认为哪个更干净。

希望有所帮助。