版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2017.08.13 |
前言
OC
和Swift
進(jìn)行混編時(shí),就需要橋接文件的設(shè)定靡砌,這樣就可以OC
和Swfit
達(dá)到混編和實(shí)現(xiàn)功能颤介。
Swift工程代碼中混編OC
下面我們先看一個(gè)例子。
1. 創(chuàng)建OC文件
先建立一個(gè)工程JJBridgeSwift
菜秦,在這個(gè)swift
工程文件里面我們新建立個(gè)OC
文件,如下圖所示舶掖。
這個(gè)時(shí)候球昨,有一點(diǎn)注意,由于工程是swift寫的眨攘,后加的OC文件主慰,只有這種第一次新建不同語(yǔ)言文件的時(shí)候會(huì)彈出下面的對(duì)話框嚣州。
3. 彈出創(chuàng)建橋接文件對(duì)話框
這里有兩個(gè)結(jié)果:
Don‘t Create
: 點(diǎn)擊這個(gè)以后,不會(huì)建立橋接文件共螺,并且以后無論在工程里面創(chuàng)建多少個(gè)異種語(yǔ)言寫的文件都不會(huì)再?gòu)棾鲞@個(gè)對(duì)話框该肴,也就是說這個(gè)對(duì)話框只自動(dòng)跳出來一次。Create Bridging Header
:點(diǎn)擊這個(gè)就會(huì)創(chuàng)建橋接文件藐不,如下所示匀哄。
我這里點(diǎn)擊Create Bridging Header
。
4. 橋接文件自動(dòng)配置
我這里點(diǎn)擊的創(chuàng)建橋接文件雏蛮,下面就要對(duì)橋接文件進(jìn)行配置涎嚼。
注意:我這里單擊的是自動(dòng)創(chuàng)建橋接文件,所以工程已經(jīng)給配置好了挑秉,并不需要我們手動(dòng)進(jìn)行配置法梯,可以看見如下圖所示。
5. 代碼驗(yàn)證
下面我們就看一下代碼驗(yàn)證衷模。
1. AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds);
let vc = JJProjectSwiftVC()
let nav = UINavigationController(rootViewController: vc)
window?.rootViewController = nav
window?.makeKeyAndVisible()
return true
}
}
2. JJProjectSwiftVC.swift
import UIKit
class JJProjectSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
let vc = JJAddOCVC()
vc.label = 10;
}
}
3. JJAddOCVC.h
#import <UIKit/UIKit.h>
@interface JJAddOCVC : UIViewController
@property (nonatomic, assign) NSInteger label;
@end
4. JJAddOCVC.m
#import "JJAddOCVC.h"
@interface JJAddOCVC ()
@end
@implementation JJAddOCVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - Getter && Setter
- (void)setLabel:(NSInteger)label
{
_label = label;
NSLog(@"%ld", self.label);
}
@end
下面看輸出結(jié)果
2017-08-13 19:25:13.525795+0800 JJBridgeSwift[9331:4127976] 10
至此鹊汛,swift
工程中混編OC
文件結(jié)束了,下面我們就看手動(dòng)的配置橋接文件的過程阱冶。
6. 手動(dòng)創(chuàng)建橋接文件
首先創(chuàng)建一個(gè)OC
文件JJAddManualVC
刁憋,設(shè)置橋接文件。
我們要給橋接文件起一個(gè)名字木蹬,如下圖所示至耻。
接著就開始編輯橋接文件。
//
// Header.h
// JJBridgeSwift
//
// Created by lucy on 2017/8/13.
// Copyright ? 2017年 com.qunar.com. All rights reserved.
//
#ifndef Header_h
#define Header_h
#import "JJAddManualVC.h"
#endif /* Header_h */
接著就配置橋接文件的路徑镊叁。
這里橋接文件的配置路徑不用自己寫尘颓,雙擊直接將Header
文件拖進(jìn)去,這里要注意晦譬,拖進(jìn)去后里面顯示的是全路徑疤苹,而我們要將其設(shè)置為相對(duì)路徑,如下圖所示敛腌,刪掉綠色的部分卧土。
這里代碼就不多給出了,還是一樣的測(cè)試代碼像樊,給出輸出結(jié)果尤莺。
2017-08-13 19:53:31.431244+0800 JJBridgeSwift[9335:4132540] 10
上面給出了swift
工程里面oc
文件自動(dòng)生成橋接文件和手動(dòng)生成橋接文件的方法。
OC工程代碼中混編Swift
下面我們就看一下OC
工程中混編Swift
的情況生棍。
1. 自動(dòng)生成橋接文件
這里我點(diǎn)擊第三個(gè)生成橋接文件颤霎。
這里橋接文件里面什么都不用寫。
我們點(diǎn)擊文件JJProjectOCVC
中的JJAddSwiftVC
,就會(huì)跳轉(zhuǎn)到自動(dòng)生成的文件中友酱,這個(gè)文件是系統(tǒng)自動(dòng)生成的晴音。
// Generated by Apple Swift version 3.1 (swiftlang-802.0.53 clang-802.0.42)
#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(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# 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 float swift_float2 __attribute__((__ext_vector_type__(2)));
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
#endif
#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(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
# define SWIFT_CLASS_PROPERTY(...)
# endif
#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(__has_attribute) && __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if defined(__has_attribute) && __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if defined(__has_attribute) && __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_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
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_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
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_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(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
# if defined(__has_feature) && __has_feature(generalized_swift_name)
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
# else
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if defined(__has_feature) && __has_feature(modules)
@import UIKit;
#endif
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
@class NSBundle;
@class NSCoder;
SWIFT_CLASS("_TtC10JJBridgeVC12JJAddSwiftVC")
@interface JJAddSwiftVC : UIViewController
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end
#pragma clang diagnostic pop
下面看一下驗(yàn)證代碼。
1. JJProjectOCVC.m
#import "JJProjectOCVC.h"
#import "JJBridgeVC-Swift.h"
@interface JJProjectOCVC ()
@end
@implementation JJProjectOCVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
JJAddSwiftVC *vc = [[JJAddSwiftVC alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
}
@end
2. JJAddSwiftVC.swift
import UIKit
class JJAddSwiftVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
print("I am here")
}
}
下面看輸出結(jié)果
I am here
2. 手動(dòng)生成橋接文件
重新建立一個(gè)新的swift
文件JJAddManualSwiftVC.swift
粹污。
下面我們就看一下手動(dòng)配置橋接文件段多,也就是說在彈出創(chuàng)建橋接文件的時(shí)候選擇Don't Create
。
用同樣的方法建立一個(gè)Header
文件壮吩。下面我們就會(huì)發(fā)現(xiàn)剛才系統(tǒng)自動(dòng)生成的文件#import "JJBridgeVC-Swift.h"
中多出來新建立的swift類的相關(guān)代碼JJAddManualSwiftVC
,如下圖所示加缘。
SWIFT_CLASS("_TtC10JJBridgeVC18JJAddManualSwiftVC")
@interface JJAddManualSwiftVC : UIViewController
- (void)viewDidLoad;
- (void)didReceiveMemoryWarning;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end
SWIFT_CLASS("_TtC10JJBridgeVC12JJAddSwiftVC")
@interface JJAddSwiftVC : UIViewController
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end
我們將這文件里面所有的東西都復(fù)制到新的橋接文件Header.h
中鸭叙,這個(gè)時(shí)候我們就在OC
文件中引用頭文件Header.h
即可;還有一個(gè)方法就是不做任何處理拣宏,這個(gè)時(shí)候就需要在OC
文件中引用頭文件#import "JJBridgeVC-Swift.h"
沈贝,這樣也是可以編譯通過的。
下面對(duì)Header.h
文件進(jìn)行工程配置勋乾。
下面看一下代碼宋下。
1. JJProjectOCVC.m
#import "JJProjectOCVC.h"
//自動(dòng)
#import "JJBridgeVC-Swift.h"
//手動(dòng)
//#import "Header.h"
@interface JJProjectOCVC ()
@end
@implementation JJProjectOCVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
JJAddManualSwiftVC *vc = [[JJAddManualSwiftVC alloc] init];
vc.view.backgroundColor = [UIColor greenColor];
}
@end
2. JJAddManualSwiftVC.swift
import UIKit
class JJAddManualSwiftVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("I am also here")
}
}
下面看輸出結(jié)果
I am also here
后記
這些東西都很簡(jiǎn)單,大家看看就好辑莫,沒事的時(shí)候就總結(jié)下学歧。