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规范规定类和委托之类的东西应该以大写字母开头,方法和参数名称应以小写字母开头.
更改:
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.
| 归档时间: |
|
| 查看次数: |
8746 次 |
| 最近记录: |