【Swift 和 OC】
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】相关推荐
- swift_037(Swift之Swift和OC混编)
接触Swift有一段时间了,但是一直没有试过混合编程.难得的五一小长假,就有空简单的写写Swift和OC的混合编程的Demo. 1.新建一个空的Swift项目 注意语言选择Swift. 2.新建一个O ...
- swift与OC之间不得不知道的21点
2019独角兽企业重金招聘Python工程师标准>>> swift与OC之间不得不知道的21点 原文 http://www.cnblogs.com/dsxniubility/p/4 ...
- Swift和OC文件间的相互调用
2019独角兽企业重金招聘Python工程师标准>>> 公共文件/桥接的方法 2016/1/26 13:33 Swift使用OC文件方法 看完上面内容之后,你只需要这 ...
- 在项目里交叉使用Swift和OC
wift and Objective-C in the Same Project 在项目里交叉使用Swift和OC Swift与OC的兼容性使得你可以在项目里使用Swift+OC的方式编写应用程序,称 ...
- 在项目里交叉使用Swift和OC【转】
Swift and Objective-C in the Same Project 在项目里交叉使用Swift和OC Swift与OC的兼容性使得你可以在项目里使用Swift+OC的方式编写应用程序, ...
- IOS中的swift和oc关于对象模型的description方法重写
IOS中的swift和oc关于对象模型的description方法重写 先讲OC的,oc比较重要,放在最前面. 首先创建一个cocoa Touch Class,继承NSObject, 命名Person ...
- swift 打包sdk_在封装SDK中Swift和OC混编之相互调用
oc和swift混编之相互调用.jpg 在非SDK中: 1.swift调用oc 步骤: 创建 工程名-Bridging-Header.h 放入oc的头文件,swift即可调用 在swift项目中或者在 ...
- swift和OC混编
swift和OC混编
- Swift与OC混编过程中的配置
女主宣言 在使用Swift进行iOS开发的过程中,经常涉及到Swift与OC混编的情况,有时主工程是OC的需要另外编入Swift代码,而有时主工程是Swift的需要另外编入OC代码.这其中涉及到修改一 ...
- swift导入oc第三方库
swift导入oc第三方库 前言 对于ios开发而言,目前很多第三方库或者demo还是以oc为主,swift相关的资料很少,这篇文章就结合博主的开发实例对在swift工程中导入并使用oc版本的第三方库 ...
最新文章
- oracle23290,详细介绍Oracle数据库EM Console重建过程
- linux pwn练习0x02
- 时间序列分类算法简介及其在能耗数据分类上的应用
- 完整的OTT直播点播系统都有哪些功能?
- c#实现Socket网络编程
- 练习_用if语句实现考试成绩划分
- 这6部顶级数学纪录片,告诉你数学一点都不无趣!
- 8086地址传送指令LEA
- LeetCode 436. 寻找右区间(二分查找)
- 2017.0622.《计算机组成原理》-虚拟存储器和主存
- JAVA编程思想课程视频
- 明星也爱字体——赵丽颖秀气字体:(江湖少女两版)蓄势待发
- BCNF范式(修正的第三范式)、第四范式和第五范式
- GEE实战4:利用GEE获取进行气温空间随机采样【随机采样】
- MySQL008:数据库引擎,如何设置引擎独立空间
- mysql查询近一年数据
- 【线代】矩阵的秩(秩:非零子式的最高阶数)
- RPG Maker更改界面分辨率并且制作炫酷界面
- [系统资源攻略]IO第二篇
- js MD5的6种实现方式