Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.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 不匹配的-init方法名称_Objective C_Xcode - Fatal编程技术网

Objective c 不匹配的-init方法名称

Objective c 不匹配的-init方法名称,objective-c,xcode,Objective C,Xcode,我发现了一个奇怪的场景,它在XCode中生成一个编译器警告,我认为这不是一个有效的警告 例如,我创建了两个类ClassA和ClassB,它们都有一个名为-initWithSomething的init方法: 一个接受(NSDate*)作为“某物”,另一个接受(NSString*) A类 // ClassA.h #import <Foundation/Foundation.h> @interface ClassA : NSObject { } -(id)initWithSomethin

我发现了一个奇怪的场景,它在XCode中生成一个编译器警告,我认为这不是一个有效的警告

例如,我创建了两个类ClassA和ClassB,它们都有一个名为-initWithSomething的init方法: 一个接受(NSDate*)作为“某物”,另一个接受(NSString*)

A类

// ClassA.h
#import <Foundation/Foundation.h>

@interface ClassA : NSObject {
}
-(id)initWithSomething:(NSDate *)something;
@end

// ClassA.m
#import "ClassA.h"

@implementation ClassA
-(id)initWithSomething:(NSDate *)something {
    if (self = [super init]) {
    }
    return self;
}
@end
这是一个编译器错误吗?这两行似乎都不应该产生警告,特别是因为初始化“classB2”的行不产生警告。
这段代码实际上运行良好,正确的类'-initWithSomething:被调用并传递适当类型的参数

显然,更显式的方法名可以避免这个问题,但是我想知道为什么编译器不能处理这个问题

注意
我应该补充一点,这似乎只发生在-init方法中,任何其他实例或类函数似乎都不会产生警告

我认为问题在于
+alloc
返回一个通用的
id

这意味着可以对其调用任何方法,编译器将看到导入的第一个具有签名
-initWithSomething
的方法用于类
A
,该类需要类型为
NSDate*
的对象

另外,我确信方法
+stringWithFormat
返回一个
id
,该id可以与
NSDate
兼容

编辑:

此问题的简单解决方案:

@interface ClassA

+(ClassA *) typeSafeAlloc;

// ...
@end

@implementation ClassA

+(ClassA *) typeSafeAlloc
{
    // self is the class variable,  which is the same as:
    // return [ClassA alloc];
    return [self alloc];
}
@end

并对ClassB重复该过程(typeSafeAlloc返回
ClassB
对象)

查看
+stringWithFormat

返回使用给定格式字符串作为模板创建的字符串,其余参数值将被替换到该模板中

+(id)stringWithFormat:(NSString*)格式,…

(来自)


编译器知道字符串是一个
NSString*
,与
@“literals”
相同。然而,
id
可以是任何东西(甚至是
NSSDate*
)。

alloc返回一个id类型的对象,因此编译器假定
initWithSomething
属于
类A
(它遇到的第一个具有方法名的类接口)

糟糕的
[(ClassB*)[ClassB alloc]initWithSomething:string]应该可以解决这个问题。

我不知道为什么会有人对此投反对票,这是一个很好的问题
#import "ExampleClass.h"
#import "ClassA.h"
#import "ClassB.h"

@implementation ExampleClass

-(void)doSomething {
    NSDate *date = [NSDate date];
    NSString *string = [NSString stringWithFormat:@"Test"];

    ClassA *classA = [[ClassA alloc] initWithSomething:date];
    ClassB *classB = [[ClassB alloc] initWithSomething:string]; // Produces "Incompatible pointer types sending 'NSString *' to parameter of type 'NSDate *'
    ClassB *classB2 = [[ClassB alloc] initWithSomething:[NSString stringWithFormat:@"Test"]]; // Does NOT produce a warning
    ClassB *classB3 = [[ClassB alloc] initWithSomething:@"Test"]; // Produces the same warning as above.

    [classA release];
    [classB release];
    [classB2 release];
    [classB3 release];
}
@interface ClassA

+(ClassA *) typeSafeAlloc;

// ...
@end

@implementation ClassA

+(ClassA *) typeSafeAlloc
{
    // self is the class variable,  which is the same as:
    // return [ClassA alloc];
    return [self alloc];
}
@end