objective-c - 为什么我需要将 self 转换为 id?

标签 objective-c casting initialization

我有一个带有 (id) 参数的 init 方法:


    -(id) initWithObject:(id) obj;

我试着这样调用它:


    [[MyClass alloc] initWithObject:self];

但是 XCode 提示参数是“不同的 Objective-C 类型”(这通常表示类型不匹配或间接错误级别)。

如果我明确地将 self 转换为 (id),警告就会消失。在任何一种情况下,代码都会按预期运行。 有趣的是,在下一行中,我将 self 传递给另一种方法,该方法也采用 id,并且工作正常。

我想知道我是否遗漏了一些微妙的东西 - 还是编译器的特性?

在我确定有必要的原因之前,我并不完全愿意施放它。

[编辑]

我被要求提供更多代码。不确定还有很多其他相关的内容。这是我进行调用的实际代码。请注意,它本身位于 init 方法中。发出警告的是对 initWithSource 的调用:


-(id) initWithFrame:(CGRect) frame
{
    self = [super initWithFrame: frame];
    if( self )
    {
        delegate = nil;
        touchDelegate = [[TBCTouchDelegate alloc] initWithSource:self];
        [touchDelegate.viewWasTappedEvent addTarget: self action:@selector(viewWasTapped:)];
    }
    return self;
}

这里是被调用的 init 方法:


-(id) initWithSource:(id) sourceObject
{
    self = [super init];
    if (self != nil) 
    {
        // Uninteresting initialisation snipped
    }
    return self;
}

最佳答案

通常这意味着在不同的类上有多个 initWithSource: 方法名称,并且参数类型存在冲突。请记住,如果变量的类型为 id,则编译器不知道它是什么类。因此,如果您在 id 类型的对象上调用 initWithSource: 并且多个类都有一个 initWithSource: 方法,编译器基本上只会选择其中一个二。如果它选择了“错误的”,那么,你会得到一个“不同的 Objective-C 类型”错误。

为什么这会发生在你身上?我不是 100% 确定,但请记住 +[TBCTouchDelegate alloc] 返回一个 id。因此,链接 alloc/init 调用等同于:

id o = [TBCTouchDelegate alloc];
touchDelegate = [o initWithSource:self];

因此,您在 id 类型的变量上调用 initWithSource:。如果存在冲突的 initWithSource: 方法,您可能会遇到此编译器错误。

是否有冲突的方法?我检查了系统,唯一冲突的是 NSAppleScript:

- (id)initWithSource:(NSString *)source;

现在 NSAppleScript Foundation 的一部分,但我注意到这是 iPhone 代码。所以也许您只在为模拟器而不是设备编译时遇到此错误?

无论如何,如果这是你的问题,你可以通过将 alloc/init 分成两行来解决它:

touchDelegate = [TBCTouchDelegate alloc];
touchDelegate = [touchDelegate initWithSource:self];

现在,您正在对一个完全类型化的变量(而不是 id-typed)调用 initWithSource:,因此编译器不再需要猜测要使用哪一个挑选。或者你可以从 +alloc 转换返回值:

touchDelegate = [(TBCTouchDelegate *)[TBCTouchDelegate alloc] initWithSource:self];

另一种解决方案是重命名 initWithSource: 以避免冲突并可能使其更具描述性。您没有说明该类当前的名称,也没有说明“来源”的用途,所以我不能排除任何可能性。

关于objective-c - 为什么我需要将 self 转换为 id?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/312608/

相关文章:

ios - 为什么在使用 init(barButtonSystemItem, target, action) 初始化时 UIBarButtonItem 的目标设置为 nil?

objective-c - UIWebView 自动调整字体大小以最适合页面

ios - Objective-C ,线程 1 程序接收信号 SIGABRT

c++ - 在 std::vector 中模板化存储多个不同类型

mysql - mysql中::numeric和::text是什么意思

Scala:在扩展类时预初始化val

objective-c - 使用 NSIndexPath 作为 NSMutableDictionary 中的键的问题?

ios - Objective C - UITableView 视觉变化出现在 false if 语句中

c++ - basic_regex 使用 char32_t 抛出 bad_cast

struct - 如何创建一个使用默认值初始化的结构体?