2011-02-25 66 views
2

我有这个类:不兼容的指针t型

@interface G2Matrix : NSObject 

... 
- (id) initWithArray:(float *)val; 
... 

@end 

这条线之下给我一个警告说,第一个参数方法initWithArray有不兼容的指针类型:

float m[16]; 
... 
G2Matrix* matrix = [[[G2Matrix alloc] initWithArray:m] autorelease]; 

如果我将方法名称更改为像initWithArray1这样的警告消失。我知道基础类中的一些对象有一个名称相同的方法,但是我从NSObject派生,它没有这个方法。是什么赋予了?

附加信息 - 我从G2Matrix类中的其他init方法调用相同的initWithArray方法,但是在那里我看不到警告。

+1

[This answer](http://stackoverflow.com/questions/3671097/why-is-this-pointer-type-in​​compatible/3671255#3671255)解释了发生了什么事以及如何避免警告。 – Anna 2011-02-25 04:12:20

+0

是的,这甚至是与我在那里的答案一样导致问题的方法。 – Chuck 2011-02-25 04:28:17

回答

3

在猜测,这是一个类型的问题:

里面的其他初始化方法,你叫[self initWithArray:...]self被键入为G2Matrix*。在这种情况下,编译器可以完全解决哪个imp(C函数指针)最终将处理方法调用,并正确检测其签名(参数和返回类型)。

在常规代码中,[G2Matrix alloc]返回id。在这种情况下,编译器只能告诉方法选择器,它将在运行时绑定到imp。它必须猜测你的意思是哪一个,并且你可以从它猜到的警告中看到,因为基础类具有不同签名的initWithArray:方法。你的代码仍然工作,编译器不能确定。

为initMethod选择一个唯一名称(initWithFloats:也许?)是关闭警告的推荐方法。其他方法是:将其分成两行;或ALLOC返回值转换成正确的类:

G2Matrix *matrix = [G2Matrix alloc]; 
matrix = [[matrix initWithArray:pointerToFloats] autorelease]; 
// or 
G2Matrix* matrix = [[(G2Matrix *)[G2Matrix alloc] initWithArray:m] autorelease]; 

看上去有些奇怪,但可以让你把请客的警告-AS-错误编译器标志回来。

+0

感谢您的好解释,以及对'正确'方法名称的建议 - 'initWithFloats'听起来更正确! – tathagata 2011-02-26 15:49:10

0

@tathagata这是因为initWithArray是在NSArray类中定义的方法,所以除非子类NSArray类,否则不能使用它。

看到的NSArray

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html

PS的文档。 通过使用该方法,我的意思是覆盖现有的方法为您的目的,这不是一个好主意,你可以在文档中找到子类注释。

+3

这不是真的。使用另一种方法共享选择器的方法通常不存在问题。如果这些方法具有不同的签名(这是因为编译器需要知道签名以生成正确的代码,并且只有在知道该对象的类型时才能这样做),这对于不同的init方法来说是一个特别糟糕的主意签名(因为'alloc'总是返回一个不确定类型的对象)。 – Chuck 2011-02-25 04:22:04

+0

酷我不知道,谢谢 – Robin 2011-02-25 04:58:48

+0

@Chuck + 1,你是正确的,只要签名也是一样的,只有一个名字相同的方法才有意义。 – tathagata 2011-02-26 15:51:44