Swift类的Objective-c协议.无法识别的方法

Neo*_*amu 8 delegates protocols objective-c ios swift

我正在尝试将一些代码从Objective-c迁移到Swift,但是当我想要使用Objective-c协议符合Swift类并从objetive-c类访问此类时,我在开始时遇到问题.我做错了什么,但我没有看到.

用于测试的Objective-c协议和obj-c类(test_class.h)

#import <Foundation/Foundation.h>

@protocol test_delegate

-(void)returnData:(NSString*)data InMethod:(NSString*)method;
@end

@interface test_class : NSObject

@property (weak, nonatomic) id<test_delegate> delegate;
-(void)sendData:(NSString * )data;
@end
Run Code Online (Sandbox Code Playgroud)

Objective-c实施

#import "test_class.h"

@implementation test_class

-(id) init{
    self = [super init];
    if (self != nil){
        self.delegate= nil;
    }
    return self;
}
-(id) initWithDelegate:(id<test_delegate>) delegate{
    self = [super init];
    if (self != nil){
        self.delegate = delegate;

    }
    return self;
}


-(void)sendData:(NSString *)data{

    [self.delegate returnData:data InMethod:@"method test"];
}
@end
Run Code Online (Sandbox Code Playgroud)

Objetive-c brigde文件

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "test_class.h"
Run Code Online (Sandbox Code Playgroud)

Swift文件(FirstViewController.swift)

import UIKit

class FirstViewController: UIViewController, test_delegate {

    var test : test_class!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        test = test_class()
        test.delegate=self
        test.sendData("show in log")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func returnData(data: String!, inMethod method: String!) {
        NSLog(data)
    }


}
Run Code Online (Sandbox Code Playgroud)

最后错误编译给了我

2015-01-27 08:21:05.787 Test[4566:51164] -[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20
2015-01-27 08:21:05.792 Test[4566:51164] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Test.FirstViewController returnData:InMethod:]: unrecognized selector sent to instance 0x7fa6abd0aa20'
Run Code Online (Sandbox Code Playgroud)

这个代码,只使用Obj-c类工作正常.我做错了什么?

使用Xcode 6.1.1和部署目标iOS 8.0

先感谢您.

更新: 当从Objective-c协议实现一些方法时,Swift有一个奇怪的行为:param的名字必须以begginig上的一个小字母开头,否则,编译器会给你一个编译时错误,如果没有,给你一个运行时错误.

我发现的独特解决方案是以这种方式修改objective-c协议方法定义:

@protocol test_delegate

-(void)returnData:(NSString*)data InMethod:(NSString*)method;
@end
Run Code Online (Sandbox Code Playgroud)

至:

@protocol test_delegate

-(void)returnData:(NSString*)data inMethod:(NSString*)method;
@end
Run Code Online (Sandbox Code Playgroud)

做这个改变,它运行得很好.

如果有人对此行为有答案,欢迎发布并解释为什么会发生这种情况.

更新2: 感谢@Adam Freeman用类名和变量名来指出Swift的另一个奇怪问题.在此处复制(经他的许可)代码:

另外需要注意的是,如果您的协议委托方法将其类作为其参数之一.使用此示例:

#import <Foundation/Foundation.h>

@class TestClass;
@protocol TestDelegate
-(void)TestClass:(TestClass*)TestClass returnData:(NSString*)data inMethod:(NSString*)method;
@end

@interface TestClass : NSObject

@property (weak, nonatomic) id<TestDelegate> delegate;
-(void)sendData:(NSString * )data;
@end
Run Code Online (Sandbox Code Playgroud)

这将导致在Swift代码中找到TestClass的问题.修复是:

#import <Foundation/Foundation.h>

@class TestClass;
@protocol TestDelegate
-(void)testClass:(TestClass*)testClass returnData:(NSString*)data inMethod:(NSString*)method;
@end

@interface TestClass : NSObject

@property (weak, nonatomic) id<TestDelegate> delegate;
-(void)sendData:(NSString * )data;
@end
Run Code Online (Sandbox Code Playgroud)

顺便提一下,Swift规范规定类和委托之类的东西应该以大写字母开头,方法和参数名称应以小写字母开头.

Rob*_*son 6

更改:

func returnData(data: String!, inMethod method: String!) {
Run Code Online (Sandbox Code Playgroud)

func returnData(data: String!, InMethod method: String!) {
Run Code Online (Sandbox Code Playgroud)

它应该工作.你使用大写字母inMethod.