Swift和Objective-C混合编程

Posted zsychanpin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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使用的时候,我们使用的allocnew等创建使用的方法是继承自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文件里的类。能够使用“项目project名+ ‘-’ + 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类型的类。


差点忽略了最重要的一点:假设有什么问题或者错误,欢迎指正或者交流。


演示样例代码: 代码下载地址

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







以上是关于Swift和Objective-C混合编程的主要内容,如果未能解决你的问题,请参考以下文章

Swift和Objective-C混合编程

《从零开始学Swift》学习笔记(Day 69)——Swift与Objective-C混合编程之语言

《从零开始学Swift》学习笔记(Day 69)——Swift与Objective-C混合编程之语言

《从零开始学Swift》学习笔记(Day 69)——Swift与Objective-C混合编程之语言

Swift2.0(18)与Objective-C的混合编程

Swift与Objective-C和Cocoa混合编程的基本设置!