swift和oc

  • swift和oc的区别
  • Swift比Objective-C优势
  • swift独有
  • Swift调用OC
  • OC调用Swift
  • Swift 选择器(selector)

swift和oc的区别

1,最明显的区别:OC一个类由.h和.m两个文件组成,而swift只有.swift一个文件,所以整体的文件数量比OC有一定减少。

2,不像C语言和OC语言一样都必须有一个主函数main()作为程序的入口,swift程序从第一句开始向下顺序执行,一直到最后。(swift将全局范围内的首句可执行代码作为程序入口,swift也有main函数,只是不用我们自己编写。)

3,swift数据类型都会自动判断,只区分变量var和常量let。

4,关于BOOL类型更加严格,swift不再是OC的非0就是真,而是true才是真false才是假。

5,swift的switch语句后面可以跟各种数据类型了,如Int,字符串,元组,区间都行,并且里面不用写break。

6,swift 中可以定义不继承于其它类的类,称之为基类(base calss)。

7,final关键字

使用final关键字修饰的类,不能被其他类继承。

继承final修饰的类会报错:Inheritance from a final class ‘……’

Swift比Objective-C优势

1,Swift容易阅读,语法和文件结构简易化。

2,Swift更易于维护,文件分离后结构更清晰。

3,Swift更加安全,它是类型安全的语言:

  Swift 是一个类型安全(type safe)的语言。类型安全的语言可以让你清楚地知道代码要处理的值的类型。如果你的代码需要一个 String ,你绝对不可能不小心传进去一个 Int 。

由于 Swift 是类型安全的,所以它会在编译你的代码时进行类型检查(type checks),并把不匹配的类型标记 为错误。这可以让你在开发的时候尽早发现并修复错误。

当你要处理不同类型的值时,类型检查可以帮你避免错误。然而,这并不是说你每次声明常量和变量的时候都需 要显式指定类型。如果你没有显式指定类型,Swift 会使用类型推断(type inference)来选择合适的类型。有了类型推断,编译器可以在编译代码的时候自动推断出表达式的类型。原理很简单,只要检查你赋的值即可。

因为有类型推断,和 C 或者 Objective-C 比起来 Swift 很少需要声明类型。常量和变量虽然需要明确类型,但 是大部分工作并不需要你自己来完成。

4,Swift代码更少,简洁的语法,可以省去大量冗余代码。

5,Swift速度更快,运算性能更高。

swift独有

1、范围运算符
a…b 表示 [a,b] 包括a和b 。 (如3…5 就是范围取3,4,5)
a…<b 表示 [a,b) 包括a,不包括b 。 (如3…5 就是范围取3,4)
常见的如for循环:for i in 0…9{}
2、独有的元组类型
元组(tuples)把多个值组合成一个复合值。元组内的值可以使任意类型,并不要求是相同类型。eg:
var value = (Int,String) = (x:15,y:“abc”) 复制代码
3、swift中使用let定义常量,var定义变量
使用常量,更加安全,不能够被修改,在需要对对象进行修改的时候 只能用var修饰.
4、if let 、 guard let 的用法
缩减代码量,安全处理数据逻辑。

Swift调用OC

由于很多常用的第三方框架还是oc版本,没有swift版本,但是项目里可能需要调用那些框架的功能,所以swift语言的工程还需要用到oc版本的三方,或者公司项目需要用到swift和oc混合开发时,就涉及到了Swift调用OC或者OC调用Swift

1、手动新建一个桥接头文件,文件名格式默认为:{targetName}-Bridging-Header.h,然后在Build Settings设置路径,如下

2、或者在swift工程里新建一个oc的文件时会自动弹出弹框询问是否自动创建桥接文件,如下


想用oc的哪些头文件,在桥接头文件中导入头文件即可,例#import “Person.h”,则在swift工程中,Person类就暴漏给swift使用了
Person.h

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGINint sum(int a,int b);@interface Person : NSObject@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;@endNS_ASSUME_NONNULL_END

Person.m

#import "Person.h"@implementation Person- (instancetype)initWithAge:(NSInteger)age name:(NSString *)name{if (self = [super init]) {self.age = age;self.name = name;}return self;
}
+ (instancetype)personWithAge:(NSInteger)age name:(NSString *)name{return [[self alloc] initWithAge:age name:name];
}+ (void)run{NSLog(@"Person + run");}
- (void)run{NSLog(@"%zd %@-run",_age,_name);}+ (void)eat:(NSString *)food other:(NSString *)other{NSLog(@"Person + eat %@ %@",food,other);
}
- (void)eat:(NSString *)food other:(NSString *)other{NSLog(@"%zd %@ - eat %@ %@",_age,_name,food,other);
}
@endint sum(int a,int b){return a+b;}

swift文件中Swift代码

let p = Person(age: 10, name: "jack")
p.age = 18
p.name = "Rose"
p.run() //18 Rose - run
p.eat("Apple", other: "water")//18 Rose - eat Apple waterPerson.run() //Person + run
Person.eat("Pizza", other: "Banana")//Person + eat Pizza  Bananaprint(sum(10, 20)) //30

OC调用Swift

1、Xcode已经默认生成一个用于OC调用Swift的头文件,文件名格式是:{targetName}-Swift.h
这里需要注意的是:工程名如果带有中划线-时,buildsettings的路径变成了下划线_,import引用时,写下划线的文件名即可;工程名如果带有下划线_时,buildsettings的路径也是下划线,引用时会报错找不到文件。文件内部放的是swift要暴露给oc的代码,那么也不是所有的swift代码都要暴露给oc,要暴漏给oc的代码要继承NSObject

2、Swift暴露给OC的类最终继承自NSObject(原因:因为oc有runtime,runtime是要求类有isa指针,isa指针肯定是继承NSObject才有的,所以最终要继承NSObject)

3、使用@objc修饰需要暴露给OC的成员

4、使用@objcMembers修饰类

  • 代表默认所有成员都会暴露给oc(包括扩展中定义的成员)
  • 最终是否成功暴露,还需要考虑成员自身的访问级别
    例子如下:
    swift文件:
class Car: NSObject {var price:Doublevar band:String@objc init(price:Double,band:String) {self.price = priceself.band = band}func run(){print(price,band,"run")}static func run(){print("car run")}
}extension Car{@objc func test(){print(price,band,"test")}
}

OC文件:

Car *car = [[Car alloc] initWithPrice:1.55 band:@"bannana"];
[car run]; // 报错:No visible @interface for 'Car' declares the selector 'run'
[Car run]; //报错:No known class method for selector 'run'
[car test];
被@objc修饰的属性或者方法才能被调用

也可写成如下:
swift文件:

@objcMembers class Car: NSObject {var price:Doublevar band:Stringinit(price:Double,band:String) {self.price = priceself.band = band}func run(){print(price,band,"run")}static func run(){print("car run")}
}extension Car{func test(){print(price,band,"test")}
}

OC文件:

Car *car = [[Car alloc] initWithPrice:1.55 band:@"bannana"];
[car run];
[Car run];
[car test];

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

6、可以通过@objc重命名Swift暴露给OC的符号名(类名、属性名、函数名等)
swift文件:

@objc(XXCar)
@objcMembers class Car: NSObject {var price:Double@objc(name)var band:Stringinit(price:Double,band:String) {self.price = priceself.band = band}@objc(drive)func run(){print(price,band,"run")}static func run(){print("car run")}
}extension Car{@objc(exec)func test(){print(price,band,"test")}
}

OC文件:

XXCar *car = [[XXCar alloc] initWithPrice:1.55 band:@"bannana"];
car.name = @"banban";
[car drive];
[car exec];
[XXCar run];

Swift 选择器(selector)

1、Swift中依然可以使用选择器,使用#selector(name)定义一个选择器
2、必须是被@objcMembers或@objc修饰的方法才可以定义选择器。
selector(选择器)是依赖于runtime的,oc里才有runtime,纯swift里是不存在runtime的

@objcMembers class XXPerson: NSObject {func test1(v1:Int){print("test1")}func test2(v1:Int,v2:Int) {print("test2(v1:v2:)")}func test2(_ v1:Double,_ v2:Double){print("test2(_ :_ :)")}func run(){perform(#selector(test1))perform(#selector(test1(v1:)))perform(#selector(test2(v1:v2:)))perform(#selector(test2(_:_:)))perform(#selector(test2 as (Double,Double) -> Void))}
}

p.run()底层是怎么调用的?
oc文件:
Person.h

#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject@property (nonatomic,assign) NSInteger age;
@property (nonatomic,copy) NSString *name;- (instancetype)initWithAge:(NSInteger)age name:(NSString *)name;- (void)run;
@end

Person.m

#import "Person.h"
#import "ludan-Swift.h"@implementation Person- (instancetype)initWithAge:(NSInteger)age name:(NSString *)name{if (self = [super init]) {self.age = age;self.name = name;}return self;
}
- (void)run{NSLog(@"%zd %@-run",_age,_name);}
@end

swift文件:

var p:Person = Person(age: 10, name: "jack")
p.run()

从汇编来看,走runtime的机制,objc_msgSend
反过来,OC调用Swift底层又是如何调用?
swift写的类继承自NSObject类,暴漏给OC调用,同样走runtime那套机制,objc_msgSend

car.run()底层是怎么调用的?
第一种情况:

@objcMembers class Car:NSObject{var price:Doublevar band:Stringinit(price:Double,band:String) {self.price = priceself.band = band}func run(){print(price,band,"run")}static func run(){print("Car run")}
}extension Car{func test() {print(price,band,"test")}
}var car:Car = Car(price: 10.5, band: "Audi")
car.run()

在swift文件里边调用,没有走oc的runtime机制,如果想要走objc_msgSend,则在run方法前边加上dynamic关键字修饰

第二种情况(不继承自NSObject,并且没有@objcMembers修饰):

class Car{var price:Doublevar band:Stringinit(price:Double,band:String) {self.price = priceself.band = band}func run(){print(price,band,"run")}static func run(){print("Car run")}
}extension Car{func test() {print(price,band,"test")}
}var car:Car = Car(price: 10.5, band: "Audi")
car.run()

纯swift类方法调用是走虚表v-Table那一套机制

【Swift 和 OC】相关推荐

  1. swift_037(Swift之Swift和OC混编)

    接触Swift有一段时间了,但是一直没有试过混合编程.难得的五一小长假,就有空简单的写写Swift和OC的混合编程的Demo. 1.新建一个空的Swift项目 注意语言选择Swift. 2.新建一个O ...

  2. swift与OC之间不得不知道的21点

    2019独角兽企业重金招聘Python工程师标准>>> swift与OC之间不得不知道的21点 原文  http://www.cnblogs.com/dsxniubility/p/4 ...

  3. Swift和OC文件间的相互调用

    2019独角兽企业重金招聘Python工程师标准>>> 公共文件/桥接的方法 2016/1/26         13:33 Swift使用OC文件方法 看完上面内容之后,你只需要这 ...

  4. 在项目里交叉使用Swift和OC

    wift and Objective-C in the Same Project 在项目里交叉使用Swift和OC Swift与OC的兼容性使得你可以在项目里使用Swift+OC的方式编写应用程序,称 ...

  5. 在项目里交叉使用Swift和OC【转】

    Swift and Objective-C in the Same Project 在项目里交叉使用Swift和OC Swift与OC的兼容性使得你可以在项目里使用Swift+OC的方式编写应用程序, ...

  6. IOS中的swift和oc关于对象模型的description方法重写

    IOS中的swift和oc关于对象模型的description方法重写 先讲OC的,oc比较重要,放在最前面. 首先创建一个cocoa Touch Class,继承NSObject, 命名Person ...

  7. swift 打包sdk_在封装SDK中Swift和OC混编之相互调用

    oc和swift混编之相互调用.jpg 在非SDK中: 1.swift调用oc 步骤: 创建 工程名-Bridging-Header.h 放入oc的头文件,swift即可调用 在swift项目中或者在 ...

  8. swift和OC混编

    swift和OC混编

  9. Swift与OC混编过程中的配置

    女主宣言 在使用Swift进行iOS开发的过程中,经常涉及到Swift与OC混编的情况,有时主工程是OC的需要另外编入Swift代码,而有时主工程是Swift的需要另外编入OC代码.这其中涉及到修改一 ...

  10. swift导入oc第三方库

    swift导入oc第三方库 前言 对于ios开发而言,目前很多第三方库或者demo还是以oc为主,swift相关的资料很少,这篇文章就结合博主的开发实例对在swift工程中导入并使用oc版本的第三方库 ...

最新文章

  1. oracle23290,详细介绍Oracle数据库EM Console重建过程
  2. linux pwn练习0x02
  3. 时间序列分类算法简介及其在能耗数据分类上的应用
  4. 完整的OTT直播点播系统都有哪些功能?
  5. c#实现Socket网络编程
  6. 练习_用if语句实现考试成绩划分
  7. 这6部顶级数学纪录片,告诉你数学一点都不无趣!
  8. 8086地址传送指令LEA
  9. LeetCode 436. 寻找右区间(二分查找)
  10. 2017.0622.《计算机组成原理》-虚拟存储器和主存
  11. JAVA编程思想课程视频
  12. 明星也爱字体——赵丽颖秀气字体:(江湖少女两版)蓄势待发
  13. BCNF范式(修正的第三范式)、第四范式和第五范式
  14. GEE实战4:利用GEE获取进行气温空间随机采样【随机采样】
  15. MySQL008:数据库引擎,如何设置引擎独立空间
  16. mysql查询近一年数据
  17. 【线代】矩阵的秩(秩:非零子式的最高阶数)
  18. RPG Maker更改界面分辨率并且制作炫酷界面
  19. [系统资源攻略]IO第二篇
  20. js MD5的6种实现方式

热门文章

  1. linux系统清理命令行,告诉你Ubuntu系统较全面清理的方法及命令
  2. Gson的基本介绍和使用
  3. 1-n奇数之和c语言,c语言1-n奇数之和
  4. 程序员面试智力题总结
  5. 信息检索与利用(第三版)第三章信息素养
  6. 【OpenGL】笔记六、GLM配置
  7. python豆瓣镜像_pip使用豆瓣的镜像源
  8. HUAWEI 机试题:黑板上的数涂颜色
  9. Kmplayer的各种功能设置
  10. MonthCalendar上使ToolTip随鼠标位置实时变化