Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c ObjC NSNumber存储指向对象的指针,而不是返回值_Objective C_Ios8_Nsnumber - Fatal编程技术网

Objective c ObjC NSNumber存储指向对象的指针,而不是返回值

Objective c ObjC NSNumber存储指向对象的指针,而不是返回值,objective-c,ios8,nsnumber,Objective C,Ios8,Nsnumber,我编写了自己的Objective C类来处理2D向量 @interface Vector2D : NSObject { struct _vecdata { double x; double y; double x_norm; double y_norm; } _data; } @property(nonatomic) double x; //custom getter + setter @property(nona

我编写了自己的Objective C类来处理2D向量

@interface Vector2D : NSObject {
    struct _vecdata {
        double x;
        double y;
        double x_norm;
        double y_norm;
    } _data;
}

@property(nonatomic) double x; //custom getter + setter
@property(nonatomic) double y; //custom getter + setter
@property(nonatomic, readonly) double xNormed; //custom getter
@property(nonatomic, readonly) double yNormed; //custom getter

+ (id)vectorWithX:(double)x_ext andY:(double)y_ext;
- (id)initWithX:(double)x_ext andY:(double)y_ext;

[...]
- (double)length;

@end

#import <math.h>
@implementation Vector2D

+ (id)vectorWithX:(double)x_ext andY:(double)y_ext{
    return [[self alloc] initWithX:x_ext andY:y_ext];
}

- (id)initWithX:(double)x_ext andY:(double)y_ext {
    if ((self = [super init])) {
        _data.x = x_ext;
        _data.y = y_ext;
        [self normalize];
    }
    return self;
}

- (void)setX:(double)x {
    _data.x = x;
    [self normalize];
}

- (double)x {
    return _data.x;
}

- (double)xNormed {
    return _data.x_norm;
}

//setters and getter for y omitted (same as for x)

[...]

- (void)normalize {
    double abs = [self length];
    if (abs != 0) {
        _data.x_norm = _data.x/abs;
        _data.y_norm = _data.y/abs;
    }
}

- (double)length {
    return sqrt(_data.x*_data.x + _data.y*_data.y);
}

@end
由于后来我显示了aNSNum的值,我注意到,所有的值(以这种方式创建的所有NSNumbers的值)都在
1.40537252E+14
(因为我后来调用[aNSNum floatValue])。 因此,我重新编译并重新运行应用程序,突然所有的值都在
4.73280427E+14
左右

所以我想知道,因为向量的长度应该在0到20000之间,但不能超过。 我开始在调试器中四处玩,以了解发生了什么,并得到了以下结果:

(lldb) po [[Vector2D vectorWithX:someXValue andY:someYValue] length]
0x0000000000000001

(lldb) po (double)[[Vector2D vectorWithX:someXValue andY:someYValue] length]
84.693565280958623

(lldb) po (unsigned long)[[Vector2D vectorWithX:someXValue andY:someYValue] length]
1

(lldb) po @([[Vector2D vectorWithX:someXValue andY:someYValue] length])
84.69356528095862

(lldb) po @((double)[[Vector2D vectorWithX:someXValue andY:someYValue] length])
84.69356528095862

(lldb) po @((unsigned long)[[Vector2D vectorWithX:someXValue andY:someYValue] length])
1

(lldb) po aNSNum
140537282189312

(lldb) po [aNSNum floatValue]
1.40537286E+14

(lldb) po (unsigned long)[aNSNum doubleValue]
<Vector2D: 0x7fd162c85800>

(lldb) po (double)[(unsigned long)[aNSNum doubleValue] length]
84.693565280958623
但希望有人能帮我把它带回一艘客轮。或者有错误的线索…

编辑: 编译器会感到困惑,因为

+(id)向量,带x:(双)x_ext安迪:(双)y_ext

id
;它不知道在运行时它将得到哪个
length
方法。将声明更改为

+(instancetype)向量,带x:(双)x_ext安迪:(双)y_ext

看看事情有多美好。 了解更多信息,请访问


您依赖于文本语法@(someNumber)来检测someNumber的类型并正确处理它,在本例中,是length方法的(double)返回值。数字文字的规则是

我认为安全的做法是,使用显式类型创建数字,而不是对变量进行类型转换,并希望编译器对其进行处理

NSNumber* aNSNum = [NSNumber numberWithDouble:[[Vector2D vectorWithX:someXValue andY:someYValue] length]];    

NSNumber文本是常量等的很好的速记,但这似乎使代码更难理解,而不是更容易理解。

这是否有效:
double len=[[Vector2D vectorWithX:someXValue andY:someYValue]length];NSNumber*aNSNum=@(len)?或者,这样做:
NSNumber*aNSNum=[NSNumber numberWithDouble:[[Vector2D vectorWithX:someXValue andY:someYValue]length]?我怀疑装箱表达式和其中的嵌套消息存在某些编译器错误。
NSNumber*aNSNum=[NSNumber numberWithDouble:[[Vector2D vectorWithX:someXValue andY:someYValue]length]似乎也没有帮助。仍然将指针作为NSNumber值获取。是的,这有点奇怪。当您尝试设置
double vectorLength=[[Vector2D vectorWithX:someXValue andY:someYValue]length]时,您得到了什么值?这可能与NSNumber毫无关系,更重要的是与具有某些奇怪行为的长度方法有关。
NSNumber*aNSNum=[NSNumber numberWithDouble:[((Vector2D*)[Vector2D vectorWithX:someXValue andY:someYValue])length]似乎起到了作用。。。似乎编译器不喜欢我的类…就像在调试器输出中一样,工作得很好:-)似乎当
length
消息返回值作为NSNumber的参数出现时,可能会有一些奇怪的编译器增强功能?!见上文。这是因为您没有提供足够的关于类方法返回类型的信息。现在对我来说一切都有意义了!
static SEL lengthSEL;
static IMP lengthIMP;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    lengthSEL = @selector(length);
    lengthIMP = class_getMethodImplementation([Vector2D class], lengthSEL);
});
Vector2D* vec = [Vector2D vectorWithX:someXValue andY:someYValue];
double len = ((double (*) (id,SEL))lengthIMP)(vec,lengthSEL);
NSNumber* aNSNum = @(len);
NSNumber* aNSNum = [NSNumber numberWithDouble:[[Vector2D vectorWithX:someXValue andY:someYValue] length]];