Swift和Objective-C混合编程
1. 首先打开Xcode6,建立一个项目,这里我使用的Objective-C默认的编程语言,项目名字叫 “SwiftAndObjective”。
2. 为了在OC中使用Swift的演示所以需要建立下面的几个类。
a)建立一个Objective-C的类继承自NSObject,名字叫OCTypeClass, 所以会自动产生两个对应的 .m 和 .h文件,这对熟悉Objective-C的人非常熟悉。
b) 尽力一个Swift类,名字叫SwiftFile1, 在点击创建的时候,会弹出一个提示问是否创建一个hander .h文件,这里必须选择是。因为如果想要在Swift中使用Objective-C的类的话,这是一个必备文件,具体使用稍后再说。结果会创建一个SwiftFile1.swift文件和一个header文件。
c)为了描述访问控制符public、private、默认等的关系,需要再创建一个Swift文件,名字叫SwiftFile2,会生成一个SwiftFile2.swift的文件。
好了文件创建部分完毕。
3. 需要定义类(因为swift可以不继承任何类,但是如果需要被Objective-C使用的时候,我们使用的alloc,new等创建使用的方法是继承自NSObject的,所以Swift中的这些类,我都继承了NSObject了)。
在SwiftFile1.swift文件中创建下面的类
import Foundation @objc public class PublicObjcTypeSwiftClass1: NSObject { var property1: Int = 0 } @objc class ObjcTypeSwiftClass1: NSObject { var property1: Int = 0 } @objc private class ObjcPrivateTypeSwiftClass1: NSObject { var property1: Int = 0 } public class PublicSwiftClass1 : NSObject { var property1: Int = 0 } class SwiftClass1: NSObject { var property1: Int = 0 } private class PrivateSwiftClass1: NSObject { var property1: Int = 0 }
在SwiftFile2.swift中创建下面的类
<pre name="code" class="objc">import Foundation @objc public class PublicObjcTypeSwiftClass2: NSObject { var property1: Int = 0 //var ocClass: OCTypeClass = OCTypeClass() //func test() { // ocClass.property1 = 0 //} } @objc class ObjcTypeSwiftClass2: NSObject { var property1: Int = 0 } @objc private class ObjcPrivateTypeSwiftClass2: NSObject { var property1: Int = 0 } public class PublicSwiftClass2: NSObject { var property1: Int = 0 } class SwiftClass2: NSObject { var property1: Int = 0 } private class PrivateSwiftClass2: NSObject { var property1: Int = 0 }
4. 因为OC文件定义之后会自动生成对应的类,所以无需再次定义了。
#import "OCTypeClass.h" #import "SwiftAndObjective-Swift.h" @implementation OCTypeClass - (void)test { PublicObjcTypeSwiftClass1 *type = [[PublicObjcTypeSwiftClass1 alloc] init]; type.property1 = 0; ObjcTypeSwiftClass1 *type2 = [[ObjcTypeSwiftClass1 alloc] init]; type2.property1 = 0; } @end
5. 打开OCTypeClass.m 文件我们需要引用Swift文件中的类。可以使用“项目工程名+ ‘-’ + Swfit.h"的形式引入所以的public的并且被标记为@objc的类(标记成@objc的类,即使不显示的写出public标记也会被Objective-C类使用)。下面的具体的代码(注意当写#import “”的使用,目前版本的Xcode不会自动识别需要的Swift的header名字,需要自己手动写,注意:不要写错项目名,如果确认是写对了,但是又一直报错可以去刷新项目,或者重启,重新build: Project-》 Clean, Project-》Build,大不了重新启动Xcode)。
6. 完成后可以通过查看源代码的形式(command + 鼠标左键)的形式查看xcode自动生成的Objective-C类。
// Generated by Swift version 1.1 (swift-600.0.54.20) #pragma clang diagnostic push #if defined(__has_include) && __has_include(<swift/objc-prologue.h>) # include <swift/objc-prologue.h> #endif #pragma clang diagnostic ignored "-Wauto-import" #include <objc/NSObject.h> #include <stdint.h> #include <stddef.h> #include <stdbool.h> #if defined(__has_include) && __has_include(<uchar.h>) # include <uchar.h> #elif !defined(__cplusplus) || __cplusplus < 201103L typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #endif typedef struct _NSZone NSZone; #if !defined(SWIFT_PASTE) # define SWIFT_PASTE_HELPER(x, y) x##y # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) #endif #if !defined(SWIFT_METATYPE) # define SWIFT_METATYPE(X) Class #endif #if defined(__has_attribute) && __has_attribute(objc_runtime_name) # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) #else # define SWIFT_RUNTIME_NAME(X) #endif #if !defined(SWIFT_CLASS_EXTRA) # define SWIFT_CLASS_EXTRA #endif #if !defined(SWIFT_PROTOCOL_EXTRA) # define SWIFT_PROTOCOL_EXTRA #endif #if !defined(SWIFT_CLASS) # if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted) # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA # else # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA # endif #endif #if !defined(SWIFT_PROTOCOL) # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA #endif #if !defined(SWIFT_EXTENSION) # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) #endif #if !defined(OBJC_DESIGNATED_INITIALIZER) # if defined(__has_attribute) && __has_attribute(objc_designated_initializer) # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) # else # define OBJC_DESIGNATED_INITIALIZER # endif #endif #if defined(__has_feature) && __has_feature(modules) @import ObjectiveC; #endif #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" #pragma clang diagnostic ignored "-Wduplicate-method-arg" SWIFT_CLASS("_TtC17SwiftAndObjective19ObjcTypeSwiftClass1") @interface ObjcTypeSwiftClass1 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective19ObjcTypeSwiftClass2") @interface ObjcTypeSwiftClass2 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective25PublicObjcTypeSwiftClass1") @interface PublicObjcTypeSwiftClass1 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective25PublicObjcTypeSwiftClass2") @interface PublicObjcTypeSwiftClass2 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective17PublicSwiftClass1") @interface PublicSwiftClass1 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective17PublicSwiftClass2") @interface PublicSwiftClass2 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective11SwiftClass1") @interface SwiftClass1 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end SWIFT_CLASS("_TtC17SwiftAndObjective11SwiftClass2") @interface SwiftClass2 : NSObject @property (nonatomic) NSInteger property1; - (instancetype)init OBJC_DESIGNATED_INITIALIZER; @end #pragma clang diagnostic pop
7. 下面开始在Swift文件中使用Objective-C的类。
a)打开xcode自动为我们生成的SwiftAndObjective-Bridging-Header.h文件, 导入暴露给swift的类。
这里为了方便就使用刚刚定义的类,只是为了演示:
#import "OCTypeClass.h"
b)然后我们什么都不需要做了,直接在Swfit文件中实现吧。
import Foundation @objc public class PublicObjcTypeSwiftClass2: NSObject { var property1: Int = 0 var ocClass: OCTypeClass = OCTypeClass() func test() { ocClass.property1 = 0 } } @objc class ObjcTypeSwiftClass2: NSObject { var property1: Int = 0 } @objc private class ObjcPrivateTypeSwiftClass2: NSObject { var property1: Int = 0 } public class PublicSwiftClass2: NSObject { var property1: Int = 0 } class SwiftClass2: NSObject { var property1: Int = 0 } private class PrivateSwiftClass2: NSObject { var property1: Int = 0 }
注意:
1. 如果想把一个Swfit类暴露给Objective-C的话需要标识@objc
2. 对于private类型的Swift类,只能在所定义的Swift文件中被使用。
3. 在一个Swift文件中的类,只能访问外部Swift文件中定义的public类型的类。
差点忽略了最重要的一点:如果有什么问题或者错误,欢迎指正或者交流。
示例代码: 代码下载地址
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。