程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Swift和Objective-C混合編程

Swift和Objective-C混合編程

編輯:關於C語言

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中創建下面的類

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()
# include 
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include 
#include 
#include 
#include 

#if defined(__has_include) && __has_include()
# include 
#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類型的類。


差點忽略了最重要的一點:如果有什麼問題或者錯誤,歡迎指正或者交流。


示例代碼: 代碼下載地址

http://download.csdn.net/detail/liyan223/8070805







  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved