标签:
开发中常见错误和警告总结(十六)
Objective-c巧妙调用不兼容的Swift方法
在Objective-c中调用Swift类中的方法时,由于部分Swift语法不支持转换,会遇到无法找到对应方法的情况,如下:
1 import UIKit 2 enum HTTPState { 3 case Succed, Failed, NetworkError, ServerError, Others 4 } 5 class ILHTTPRequest: NSObject { 6 class func requestLogin(userName: String, password: String, callback: (state: HTTPState) -> (Void)) { 7 dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void in 8 NSThread.sleepForTimeInterval(3) 9 dispatch_async(dispatch_get_main_queue(), { () -> Void in 10 callback(state: HTTPState.Succed) 11 }) 12 }) 13 } 14 }
对应的$(SWIFT_MODULE_NAME)-Swift.h文件为:
1 SWIFT_CLASS("_TtC12ILSwiftTests13ILHTTPRequest") 2 @interface ILHTTPRequest : NSObject 3 - (SWIFT_NULLABILITY(nonnull) instancetype)init OBJC_DESIGNATED_INITIALIZER; 4 @end
从上面的头文件中可以看出,方法requestLogin使用了不支持的Swift枚举,转换时方法被自动忽略掉,有以下两种办法,可以巧妙解决类似问题:
用支持的Swift语法包装
在Swift文件中,添加一个可兼容包装方法wrapRequestLogin,注意此方法中不能使用不兼容的类型或者语法
1 import UIKit 2 enum HTTPState: Int { 3 case Succed = 0, Failed = 1, NetworkError = 2, ServerError = 3, Others = 4 4 } 5 class ILHTTPRequest: NSObject { 6 class func requestLogin(userName: String, password: String, callback: (state: HTTPState) -> (Void)) { 7 dispatch_async(dispatch_get_global_queue(0, 0), { () -> Void in 8 NSThread.sleepForTimeInterval(3) 9 dispatch_async(dispatch_get_main_queue(), { () -> Void in 10 callback(state: HTTPState.Succed) 11 }) 12 }) 13 } 14 class func wrapRequestLogin(userName: String, password: String, callback: (state: Int) -> (Void)) { 15 self.requestLogin(userName, password: password) { (state) -> (Void) in 16 callback(state: state.rawValue) 17 } 18 } 19 }
对应的$(SWIFT_MODULE_NAME)-Swift.h文件为:
1 SWIFT_CLASS("_TtC12ILSwiftTests13ILHTTPRequest") 2 @interface ILHTTPRequest : NSObject 3 + (void)wrapRequestLogin:(NSString * __nonnull)userName password:(NSString * __nonnull)password callback:(void (^ __nonnull)(NSInteger))callback; 4 - (SWIFT_NULLABILITY(nonnull) instancetype)init OBJC_DESIGNATED_INITIALIZER; 5 @end
此时,我们可以在Objective-c中直接使用包装后的方法wrapRequestLogin
巧妙使用继承
使用继承可以支持所有的Swift类型,主要的功能在Objective-c中实现,不支持的语法在Swift文件中调用,例如,ILLoginSuperController做为父类
1 @interface ILLoginSuperController : UIViewController 2 @property (weak, nonatomic) IBOutlet UITextField *userNameField; 3 @property (weak, nonatomic) IBOutlet UITextField *passwordField; 4 - (IBAction)loginButtonPressed:(id)sender; 5 @end 6 //////////////////////////////////////////////////////////////// 7 @implementation ILLoginSuperController 8 - (IBAction)loginButtonPressed:(id)sender 9 { 10 } 11 @end
创建Swift文件,继承自ILLoginSuperController,在此Swift文件中调用那些不支持的语法
1 import UIKit 2 class ILLoginController: ILLoginSuperController { 3 override func loginButtonPressed(sender: AnyObject!) { 4 ILHTTPRequest.requestLogin(self.userNameField.text, password: self.passwordField.text) { (state) -> (Void) in 5 //具体业务逻辑 6 } 7 } 8 }
标签:
原文地址:http://www.cnblogs.com/iCocos/p/4761815.html