CGFloats,浮点数设置为零

时间:2011-02-16 01:10:30

标签: iphone objective-c getter-setter

我有一个自定义类Custom.mm,我试图在我的控制器类MainController中使用setter设置一个浮点值。 Custom实例被输入为id,因为它是一个Obj-C ++文件,并且在编译时指向正确的类对我来说效果很好。一切正常,实例已经过验证。如果我将amount变量设置为int类型并传递ints则可以正常工作。与任何其他值或对象相同 - 浮点数除外。出于某种原因,在Custom.mm类中将float(float,CGFloat等)设置为0。这不是NSLog或其他任何问题 - 我用断点检查了数量变量,一切正常但浮动。

    //Custom.h
 @interface Custom : UIView  
{

      CGFloat amount;

}

 @property CGFloat amount;

 @end

    //Custom.mm
@implementation Custom
@synthesize  amount;

- (id) initWithCoder:(NSCoder*)coder
{
    if ((self = [super initWithCoder:coder])) 
    {
        //set initial value to 1
        self.amount = 1.0;  //verified as 1.0
    }
    return self;
}

    //MainController.h
@interface MainController : UIViewController 
{
    IBOutlet id customInstance; //IB points to the CustomView class
}

    //MainController.m
@implementation MainController

-(void)viewDidLoad
 {
        [super viewDidLoad];

        //Checking this value in Custom.mm via the debugger shows it as being 0, 
        //when before it was 1.0. 
        [customInstance setAmount:2.0]; 
  }

 @end

2 个答案:

答案 0 :(得分:6)

我能够自己重现这个;你遇到了一个有趣的现象。

您的问题是编译器无法查看setAmount:方法的定义。因此,它不知道方法所期望的参数的正确类型。在这种情况下,编译器假定所有参数都是“...”类型,返回值的类型为“id”。但是你传递了一个CGFloat,而不是'......'。

Objective-C是一种动态语言,所以即使编译器不知道目标方法是否存在,它仍然会很高兴地打包参数并尝试调用它。 但是,在大多数体系结构中,传递参数的方法取决于参数的类型。整数和指针参数通常在一组寄存器中传递,而浮点参数在另一组寄存器中传递,而结构通常直接在堆栈上传递。 (精确的细节取决于您正在运行的体系结构。)由于编译器无法查看setAmount:方法的定义,因此它假定参数的类型为...。根据体系结构的不同,这些寄存器可以在不同的寄存器集中传递,甚至可以在堆栈中传递。

然而,当setAmount:方法运行时,它期望传入的参数位于某组寄存器中。当然,调用者没有填充那些,因此仍设置为0.调用者将新值放在一个位置,但接收者查看另一个位置。难怪事情出错了。

解决方法很简单:在#import "Custom.h"的顶部添加MainController.m然后,编译器将能够看到setAmount:的定义当它正在编译MainController时,会因此知道将新值放在接收器期望的位置。

顺便说一句,我敢打赌,当你编译时,你会收到警告;

之类的东西
warning: no '-setAmount:' method found
warning: (Messages without a matching method signature
warning: will be assumed to return 'id' and accept
warning: '...' as arguments.)

至少,这是我得到的警告。那是编译器告诉你它在进行调用时不知道在哪里放置参数,所以它只是选择了一些并希望它有效。在这种情况下,它没有。

对于整数和其他类型正常工作,编译器对参数传递样式的猜测恰好与接收者期望的匹配。这是一个简单的运气问题。

答案 1 :(得分:0)

看起来你还没有为MainController的customInstance变量分配一个Custom对象,所以它没有。问什么都没有,它会给你0。