从Swift对Objective-C委托调用方法

时间:2023-01-15 18:34:15

I'm writing some Swift classes that build upon functionality in our objective-c app. I have a objective-c class with a delegate that conforms to a protocol. I'm trying to call a method on that delegate from inside of a Swift class I'm simplified it down to this.

我正在编写一些基于objective-c应用程序功能的Swift类。我有一个objective-c类,它有一个符合协议的委托。我试着从Swift的内部调用这个委托的方法我将它简化为这个。

FredTestProtocol.h:

FredTestProtocol.h:

@protocol FredTestProtocol
- (void) dumbMethod;
@end

FredTestClass.h:

FredTestClass.h:

#import <Foundation/Foundation.h>
#import "FredTestProtocol.h"

@interface FredTestClass : NSObject <FredTestProtocol>
@property (nonatomic, weak) NSObject <FredTestProtocol> *delegate;
@end

FredTestClass.m:

FredTestClass.m:

#import "FredTestClass.h"

@implementation FredTestClass
- (void) dumbMethod
{
    NSLog(@"Boy, this is a dumb method");
}
@end

FredSwiftClass.swift

FredSwiftClass.swift

import Foundation

class FredSwiftClass {
    func test()
    {
        let ocObject = FredTestClass()
        ocObject.delegate.dumbMethod() // Error occurs here.
    }
}

The indicated line produces the error "'NSObject' does not have a method named 'dumbMethod'" I've tried a lot of ways to eliminate the error, to no avail. I'm sure I'm missing something really fundamental. Can someone tell me how I should go about calling the delegate method from Swift?

指示的行产生错误“'NSObject'没有一个名为'dumbMethod'的方法”我已经尝试了很多方法来消除错误,但没有任何效果。我肯定我漏掉了一些基本的东西。有人能告诉我如何从Swift调用委托方法吗?

2 个解决方案

#1


2  

When Swift examines the property delegate it simply sees that is is an NSObject and the fact that you have noted that it implements a protocol is ignored. I can't find any specific documentation as to why this is the case.

当Swift检查属性委托时,它只看到它是一个NSObject,并且您已经注意到它实现了一个协议被忽略了。我找不到任何具体的文件来说明为什么会这样。

You can address this in a couple of ways.

你可以用几种方法来解决这个问题。

First, you can redefine your delegate property to use class anonymity, then Swift will just see it as some object that implements the protocol -

首先,您可以重新定义您的委托属性以使用类匿名性,然后Swift将看到它作为实现协议的对象

FredTestClass.h

FredTestClass.h

#import <Foundation/Foundation.h>
#import "FredTestProtocol.h"

@interface FredTestClass : NSObject <FredTestProtocol>
@property  id<FredTestProtocol> delegate;
@end  

Then your Swift code will compile as written.

然后您的Swift代码将按照编写的方式进行编译。

or you can leave your delegate definition as is and tell Swift that you want to access the delegate as an instance of an object that implements the protocol via downcast -

或者你可以保留你的委托定义,告诉Swift你想访问委托作为一个对象的实例,通过downcast -来实现协议

FredTestSwift.swift

FredTestSwift.swift

import Foundation

class FredSwiftClass {
    func test()
    {
        let ocObject = FredTestClass()
        let theDelegate=ocObject.delegate as! FredTestProtocol
        theDelegate.dumbMethod()
    }
}

#2


0  

Pretty sure I've got it.

我很确定我拿到了。

func test()
{
    let ocObject = FredTestClass()

    if let myDelegate = ocObject.delegate as? FredTestProtocol
    {
        myDelegate.dumbMethod()
    }
}

#1


2  

When Swift examines the property delegate it simply sees that is is an NSObject and the fact that you have noted that it implements a protocol is ignored. I can't find any specific documentation as to why this is the case.

当Swift检查属性委托时,它只看到它是一个NSObject,并且您已经注意到它实现了一个协议被忽略了。我找不到任何具体的文件来说明为什么会这样。

You can address this in a couple of ways.

你可以用几种方法来解决这个问题。

First, you can redefine your delegate property to use class anonymity, then Swift will just see it as some object that implements the protocol -

首先,您可以重新定义您的委托属性以使用类匿名性,然后Swift将看到它作为实现协议的对象

FredTestClass.h

FredTestClass.h

#import <Foundation/Foundation.h>
#import "FredTestProtocol.h"

@interface FredTestClass : NSObject <FredTestProtocol>
@property  id<FredTestProtocol> delegate;
@end  

Then your Swift code will compile as written.

然后您的Swift代码将按照编写的方式进行编译。

or you can leave your delegate definition as is and tell Swift that you want to access the delegate as an instance of an object that implements the protocol via downcast -

或者你可以保留你的委托定义,告诉Swift你想访问委托作为一个对象的实例,通过downcast -来实现协议

FredTestSwift.swift

FredTestSwift.swift

import Foundation

class FredSwiftClass {
    func test()
    {
        let ocObject = FredTestClass()
        let theDelegate=ocObject.delegate as! FredTestProtocol
        theDelegate.dumbMethod()
    }
}

#2


0  

Pretty sure I've got it.

我很确定我拿到了。

func test()
{
    let ocObject = FredTestClass()

    if let myDelegate = ocObject.delegate as? FredTestProtocol
    {
        myDelegate.dumbMethod()
    }
}