2

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

    //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
4

2 回答 2

6

我能够自己复制它;你遇到了一个有趣的现象。

您的问题是编译器看不到该setAmount:方法的定义。结果,它不知道该方法所期望的参数的正确类型。在这种情况下,编译器假定所有参数的类型为“...”,返回值的类型为“id”。但是您传递的是 CGFloat,而不是“...”。

Objective-C 是一种动态语言,所以即使编译器不知道目标方法是否存在,它也会愉快地打包参数并尝试调用它。然而,在大多数架构上,传递参数的方法取决于参数的类型。整数和指针参数通常在一组寄存器中传递,而浮点参数在另一组中传递,而结构通常直接在堆栈上传递。(精确的细节取决于你在哪个架构上运行。)由于编译器看不到setAmount:方法的定义,它假定参数是 type ...。根据架构的不同,它们可能会在一组不同的寄存器中传递,甚至在堆栈上。

但是,当该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.)

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

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

于 2011-02-17T03:35:03.663 回答
0

看起来您还没有将自定义对象分配给 MainController 的customInstance变量,所以它是 nil。要求 nil 任何东西,它会给你 0。

于 2011-02-16T23:48:27.497 回答