嗨,首先让我说谢谢你帮助我解决这个问题。我目前正在尝试学习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;
}
编辑:所有语法提示,一般实施等都受到赞赏并将投入使用!
答案 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。请注意,您也可以同时使用这两个级别。
在我给出答案之前,下面是苹果文档的链接。
“使用十进制数字”部分&#39;是你关心的主要人物,但是从那以后
这里使用NSDecimal结构进行数学运算的函数。
您的类将属性定义为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];
}
我认为哪个更干净。
希望有所帮助。