在同一个工程中是可以同时使用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并重载父类方法出现编译异常
父类代码:
@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: 开头的方法、IMP 、NSInvocation 已经去掉了,用什么替代?
The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe. 摘自
Objective-C中的执行指定对象的指定方法:
但Swift中以performSelector: 开头的方法、IMP 、NSInvocation 已经去掉了。。。
Swift的NSInvocationOperation 类、NSObject 的func 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 类型,需要转换成指定的闭包 类型,然后执行。
|
请发表评论