欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Swift与Objective-C交互

发布时间:2025/7/14 编程问答 25 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Swift与Objective-C交互 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

在同一个工程中是可以同时使用Swift和OC的,但不可以同时出现在同一个文件中。

OC调用Swift相关信息的方法

***.m文件中导入工程名-Swift.h即可。
如工程名为ABC,则在需要使用Swift相关信息的.m文件中#import "ABC-Swift.h"即可。

Swift调用OC相关信息的方法

当在Swift/OC工程中创建OC/Swift文件时,会有提示,如下图
点击Yes,会创建一个工程名-Bridging-Header.h的文件,将Swift使用的相关OC的.h文件导入(#import "****.h")就可以在Swift中使用了。

参照:https://itunes.apple.com/us/book/using-swift-cocoa-objective/id888894773?mt=11

注意点

遇到问题

  • 1、Swift继承Objective-C并重载父类方法出现编译异常
  • 2、Swift中NSClassFromString方法对Swift的类无作用
  • 3、Swift中以performSelector:开头的方法、IMPNSInvocation已经去掉了,用什么替代?
  • 4、Swift中AnyObject如何转换为闭包类型?

可能有未解决的问题,如果您有方法解决,请留言:) 无比感谢!

1、Swift继承Objective-C并重载父类方法出现编译异常

父类代码:

@interface SuperClass : NSObject - (NSArray *) arrayWithString:(NSString *)string array:(NSArray *)array dictionary:(NSDictionary *)dictionary number:(NSNumber *)number; @end @implementation SuperClass - (NSArray *) arrayWithString:(NSString *)string array:(NSArray *)array dictionary:(NSDictionary *)dictionary number:(NSNumber *)number { return @[]; } @end

*-Bridging-Header.h文件中导入.h头文件:#import "SuperClass.h"

子类代码:

class SubClass: SuperClass { override func arrayWithString(string: NSString, array: NSArray, dictionary: NSDictionary, number: NSNumber) -> NSArray { return ["2"] } }

有参数或者有返回的Objective-C方法被swift重载的时候就会有编译异常:

Overriding method with selector '***' has incompatible type '****'

解决方法:
如图

可以在Quick Help中看到方法的参数和返回值的类型 上面子类代码改为如下即可:

class SubClass: SuperClass { override func arrayWithString(string: String, array: AnyObject[], dictionary: NSDictionary, number: NSNumber) -> AnyObject[] { return ["2"] } }

2、Swift中NSClassFromString方法对Swift的类无作用

代码例子如上

在Swift类中使用

var superC: AnyClass! = NSClassFromString("SuperClass") println(NSStringFromClass(superC)) // 输出SuperClass var subC: AnyClass! = NSClassFromString("SubClass") println(NSStringFromClass(subC)) // 输出nil

暂时解决办法:

var subC: AnyClass! = SubClass.self println(NSStringFromClass(subC)) // 输出SubClass

解决方法:
在SubClass上增加@objc(SubClass)SubClass类变为:

@objc(SubClass) class SubClass: SuperClass {...}

3、Swift中以performSelector:开头的方法、IMPNSInvocation已经去掉了,用什么替代?

The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe. 摘自

Objective-C中的执行指定对象的指定方法:

  • 使用以performSelector:开头的方法;
  • 使用IMP
  • 使用NSMethodSignatureNSInvocation,见Object-C中使用NSInvocation在Runtime时调用方法时传入多个参数的方法

但Swift中以performSelector:开头的方法、IMPNSInvocation已经去掉了。。。

Swift的NSInvocationOperation类、NSObjectfunc forwardInvocation(anInvocation: NSInvocation!)都有对NSInvocation的引用,为毛点进去神马都没有呢。。。或许还是因为Xcode6 beta2还是beta版本吧。。。beta3也是如此。。。

那么用什么替代呢?

我目前还是使用Objective-C配合解决这个问题
Xcode6 beta3中的Swift加入了IMP,但和Objective-C中的IMP完全不一样。还不知道怎么用。

4、Swift中AnyObject如何转换为闭包类型?

Swift includes a protocol type named AnyObject that represents any kind of object, just as id does in Objective-C. The AnyObject protocol allows you to write type-safe Swift code while maintaining the flexibility of an untyped object. Because of the additional safety provided by the AnyObject protocol, Swift imports id as AnyObject.
Swift closures and Objective-C blocks are compatible, so you can pass Swift closures to Objective-C methods that expect blocks. Swift closures and functions have the same type, so you can even pass the name of a Swift function. 摘自
如上所述,Swift中的AnyObject等价于Objective-C中的id,Swift中的闭包等价于Objective-C中的Block。但在实际应用中却有问题,比如Objective-C中id类型可以强制转换为Block,如下:

typedef void(^BasicBlock)(void); id b1 = ^{ }; BasicBlock b1 = b1;

但Swift中如果强制转换就有error了,如下:

typealias BasicBlock = () -> Void func a() -> BasicBlock { func b(){ println("123213"); } return b; } var c:AnyObject = a(); // error

遇到的问题是:Swift通过问题3返回了一个Block(闭包),但其返回出来的是id类型,在Swift中接收到的是AnyObject类型,需要转换成指定的闭包类型,然后执行。

转载于:https://www.cnblogs.com/Free-Thinker/p/4992693.html

总结

以上是生活随笔为你收集整理的Swift与Objective-C交互的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。