JHHK

欢迎来到我的个人网站
行者常至 为者常成

18_01、OC到Swift(一)

目录

mark标记

/// 一、mark标记
func markUse() -> Void {
    //MARK: - test方法
    //MARK: test1
    //MARK: test1
    
    //MARK: - 测试方法
    //TODO:标记未完成任务
    //FIXME:待修复问题
    
    //警告 可用于标记未完成
    #warning("undo")
    
    
    func test()->Int{
        #warning("undo")
        fatalError()
    }
}

条件编译

/// 二、条件编译
func conditonCompile() -> Void {
    //操作系统:macOS\iOS\tvOS\watchOS\Linux\Android\Windows\FreeBSD
    #if os(iOS)
        print("os(macOS) || os(iOS)")
    #elseif os(macOS)
        print("os(macOS)")
    #endif


    //CPU架构:i386\x86_64\arm\arm64
    #if arch(arm64)
        print("arch(x86_64) || arch(arm64)")
    #elseif arch(x86_64)
        print("arch(x86_64)")
    #endif


    //swift 版本
    #if swift(<6)&&swift(>=3)
        print("swift(<6)&&swift(>=3)")
    #endif


    //模拟器
    #if targetEnvironment(simulator)
        print("targetEnvironment(simulator)")
    #endif

    //可以导入某模块
    #if canImport(Foundation)
        print("canImport(Foundation)")
    #endif
    
    
    //MARK: - 总结
    #if os(macOS) || os(iOS)
    
    #elseif arch(x86_64) || arch(arm64)
    
    #elseif swift(<5)&&swift(>=3)
    
    #elseif targetEnvironment(simulator)
    
    #elseif canImport(Foundation)
    
    #else
    
    #endif
    
}

系统版本检测

/// 三、系统版本检测
func systemVersionCheck() -> Void {
    if #available(iOS 10,macOS 10.12, *){
        //对于iOS平台,只在iOS10及以上版本执行
        //对于macOS平台,只在macOS 10.12及以上版本执行
        //最后的*表示在其他所有平台都执行
    }
    
    
    //Person类
    //对于iOS平台,只在iOS10及以上版本存在
    //对于macOS平台,只在macOS 10.15及以上版本存在
    @available(iOS 10, macOS 10.15,*)
    class Person{}
    
    //let person = Person()//会报错:Person' is only available in macOS 10.15 or newer
    
    
    if #available(macOS 10.15, *){
        let person1 = Person()
        print(person1)
    }
    
    
    
    struct Student{
        //重命名提示
        @available(*,unavailable,renamed: "study")
        func _study() {}
        func study() {}
        
        //不赞成 但可以使用
        @available(iOS,deprecated: 11)
        @available(macOS,deprecated: 10.12)
        func run() {print("run")}
    }
    
    let  stu = Student()
    //stu._study()//会报错:_study()' has been renamed to 'study'
    stu.study()
    stu.run()//'run()' was deprecated in macOS 10.12
}

swift调用oc

新建1个桥接头文件,文件名格式默认为:{targetName}-Bridging-Header.h

在 {targetName}-Bridging-Header.h 文件中 #import OC需要暴露给Swift的内容

img

LCClientDemo-commond-Bridging-Header.h文件内容

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "MJPerson.h"

MJPerson.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MJPerson : NSObject

int sum(int a, int b);

@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString * name;//

//-(instancetype)initWithAge:(NSInteger)age name:(NSString*)name;
+(instancetype)personWithAge:(NSInteger)age name:(NSString*)name;

-(void)run;
+(void)run;

-(void)eat:(NSString*)food other:(NSString*)other;
+(void)eat:(NSString*)food other:(NSString*)other;

void ocTestFun(void);


@end

NS_ASSUME_NONNULL_END

MJPerson.m

#import "MJPerson.h"
#import "LCClientDemo_commond-Swift.h"

@implementation MJPerson 
int sum(int a, int b){
    return a+b;
}

-(instancetype)initWithAge:(NSInteger)age name:(NSString*)name{
    NSLog(@"实例方法");
    if (self = [super init]) {
        self.age = age;
        self.name = name;
    }
    return self;
}

+(instancetype)personWithAge:(NSInteger)age name:(NSString*)name{
    NSLog(@"类方法");
    MJPerson * person = [[self alloc] init];
    person.age = age;
    person.name = name;
    return person;
//    return [[self alloc] initWithAge:age name:name];
}

-(void)run{
    NSLog(@"%zd %@ -run",_age,_name);
}

+(void)run{
    NSLog(@"Person + run");
}

-(void)eat:(NSString*)food other:(NSString*)other{
    NSLog(@"%zd %@ -eat %@ %@",_age,_name,food,other);
}

+(void)eat:(NSString*)food other:(NSString*)other{
     NSLog(@"Person+eat %@ %@",food,other);
}



void ocTestFun(){
    NSLog(@"testFun\n");
    
    //LCClientDemo_commond-Swift.h 会在该文件内生成相应的oc代码
    //调用Swift中代码
    Car * car = [[Car alloc] initWithPrice:20.5 band:@"Bens"];
    car.band = @"BMW";
    car.price = 108.5;
    [car run];
    [car test];
    [Car run];
}

@end
/// 四、swift调用oc
//若果C语言暴露给Swift的函数名跟Swift中的其它函数名冲突了
//可以在Swift中使用@_silgen_name 修改C函数名
@_silgen_name("sum") func swift_sum(_ v1:Int32,_ v2:Int32)->Int32

func swiftToOc() -> Void {
    //1、Swift调用OC – Swift代码
    do{
        print("--------1---------")
        let p = MJPerson(age: 10, name: "Jack")
        p.age = 18
        p.name = "Rose"
        p.run() // 18 Rose -run
        p.eat("Apple", other: "Water") // 18 Rose -eat Apple Water
        
        MJPerson.run() // Person +run
        MJPerson.eat("Pizza", other: "Banana") // Person +eat Pizza Banana
        
        print(sum(10, 20)) // 30
    }
    
    
    //2、相当于下面的类
    do{
        print("--------2--------")
        class MJPerson{
            var age:Int
            var name:String
            init(age:Int,name:String) {
                self.age = age
                self.name = name
            }
            func eat(_ food:String,other:String) -> Void {
                print(food,other)
            }
            func run() -> Void {
                print("Run")
            }
            
            static func eat(_ food:String,other:String) -> Void {
                print(food,other)
            }
            static func run() -> Void {
                print("Run")
            }
        }
    }
    
    
    //3、
    do{
        print("--------3---------")
        func sum(_ v1:Int32, _ v2:Int32)->Int32{
            v1 - v2
        }
        print(swift_sum(11, 22))
    }
}

oc调用Swift

Xcode已经默认生成一个用于OC调用Swift的头文件,文件名格式是: {targetName}-Swift.h

img

/**
 Xcode已经默认生成一个用于OC调用Swift的头文件,文件名格式是: {targetName}-Swift.h
 
 Swift暴露给OC的类最终继承自NSObject
 
 使用@objc修饰需要暴露给OC的成员
 
 使用@objcMembers修饰类
     代表默认所有成员都会暴露给OC(包括扩展中定义的成员)
     最终是否成功暴露,还需要考虑成员自身的访问级别
 */

@objcMembers class Car:NSObject{
    var price:Double
    var band:String
    init(price:Double,band:String) {
        self.price = price
        self.band = band
    }
    
    func run() -> Void {
        print(price,band,"run")
    }
    
    static func run(){
        print("Car run")
    }
}

extension Car{
    func test() -> Void {
        print(price,band,"test")
    }
}

Xcode会根据Swift代码生成对应的OC声明,写入 {targetName}-Swift.h 文件

@interface Car : NSObject
@property (nonatomic) double price;
@property (nonatomic, copy) NSString * _Nonnull band;
- (nonnull instancetype)initWithPrice:(double)price band:(NSString * _Nonnull)band OBJC_DESIGNATED_INITIALIZER;
- (void)run;
+ (void)run;
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
+ (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable");
@end


@interface Car (SWIFT_EXTENSION(LCClientDemo_commond))
- (void)test;
@end

OC调用

#import "LCClientDemo_commond-Swift.h"

void ocTestFun(){
    NSLog(@"testFun\n");
    
    //LCClientDemo_commond-Swift.h 会在该文件内生成相应的oc代码
    //调用Swift中代码
    Car * car = [[Car alloc] initWithPrice:20.5 band:@"Bens"];
    car.band = @"BMW";
    car.price = 108.5;
    [car run];
    [car test];
    [Car run];
}

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.