从OC到Swift(一)

开篇

在简单的学习了swift语法之后,开始在项目里使用。很多东西都是别人铺好路,自己只是套用写UI而已。这里先简单过渡一下OC-Swift,后续再深入研究Swift相关知识。

Swift与OC如何互相调用

大部分项目应该都是要从OC过渡到Swift,这就避免不了混编,这里涉及到两个桥接头文件:

1. Swift调用OC {targetName}-Bridging-Header.h

作用:Swift可调用OC,在此文件中import OC的头文件

在OC工程中创建swift文件时会有此提示,点击create Xcode会帮我们生产此文件。

image.png

并且在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Bridging Header有配置路径。如果工程里没有此文件,我们可以手动创建,并且在这里配置一下,不过注意的是文件名字必须为上述格式{targetName}-Bridging-Header.h
image.png

2. OC调用Swift 一般为{targetName}-swift.h

在上面图中我们看到Objective-C Generated Interface Header Name 这里也有一个配置的文件路径,这里就是让OC可与调用Swift。需要调用swift的地方,import这个文件就可以。
名字为什们说一般为{targetName}-swift.h呢?当targetName中存在-这种情况,需要变_。 例如targetNameOC-Swift,这个头文件的名字应该是OC_Swift-Swift.h。这个文件内是swift编译生成的对应OC代码。
这个文件在工程内不能直接看到,编译后,可以通过Command+单击该文件名,就会看到具体生成的代码。

需要注意的是:
  • 在OC里如果想要调用Swift,需要在被访问的类,属性,方法前面加上@objc,并且如果是类,需要继承NSObject,否则编译也会报错。
    @objc class TestSwiftClass: NSObject { }
  • 这就又有问题了,如果一个类特别复杂都需要暴露给OC,那不是得写好多@objc?这时候可以使用@objcMembers, 这样类、类中的所有属性、方法都暴露给OC可以直接调用。
    @objcMembers class Car: NSObject { }
  • 我们还可以给swift属性、方法重新定义供OC使用的名字
@objc(realName)
var name: String; 
@objc(ocRun)
func run() {
}

以上整体下来示例:

//swift中写法
@objcMembers class TestSwiftClass: NSObject {
    @objc(realName)
    var name: String;
    var age: Int;
    init(name:String, age:Int) {
        self.name = name
        self.age = age
    }
    @objc(ocRun)
    func run() {
        
    }
}
//OC中调用
- (void)viewDidLoad {
    [super viewDidLoad];

    TestSwiftClass *obj = [[TestSwiftClass alloc]initWithName:@"zhangsan" age:12];
    obj.age = 11;
    obj.realName = @"ZhangSan";
    [obj ocRun];
}
  • 我们上面会发现swif中定义的init方法init(name:String, age:Int),而OC里面调用还是我们熟悉的样子TestSwiftClass *obj = [[TestSwiftClass alloc]initWithName:@"zhangsan" age:12];
    而且OC里面的方法 - (instancetype)initWithTitle:(NSString *)title;到Swift中调用的时候是let obj = TestOCClass(title: "title")
    这里是xcode帮我做了优化,生成对应风格的代码。
这里有个坑,就是你可能会发现在swift中无法调用一些OC的单例创建方法,比如 + (instancetype)manager, 或者+(instancetype)shareManager。后来发现需要定义一些标准名字比如default singleton shared 。不过这个问题应该在只存在某几个版本的Xcode中,目前发现Xcode11.3没有这个问题

以上大概就已经做好混编的基础了。

Selector的使用

在OC里面我们经常使用@selector(name),在swift里面只是把@替换#,例:#selector(name)

  • 注意的是,必须是被@objcMembers或@objc修饰的方法才可以定义选择器。
    为什么呢?我们可以想一下@selector(name)是依赖OC的runtime,纯swift是没有runtime的,所以既然要使用方法选择器,说明需要用到runtime,所以需要通过关键字桥接到OC。当然在swift里面也可以调用perform(#selector(name))

String的区别

我们发现swift中的String在OC中会自动转换为NSString。但是Swift中的String的用法确与OC相差很大。在系统学习之前,我两个月都没用明白(但是不能承认自己笨。嗯!咳)。
关于字符串拼接之类的就不多说了,主要说一下关于String的Index。
String的下标(Index)并不是int类型,而是String.Index,Index是个结构体


image.png

虽然他不是整形,但是他一样代表着位置。关于String类型的一些方法,.startIndex/.endIndex!,例:name.startIndex/name.endIndex代表是起始位置(第一个字符的位置)/最后位置(最后一个字符的下一位)
关于String的一些插入删除方法:

//插入
var str = "a-b"
// 插入单个字符,最后一个位置插入‘-’,结果:a-b-
str.insert("-", at: str.endIndex)
// 插入字符串使用contentsOf:末尾插入c-d,结果:a-b-c-d
str.insert(contentsOf: "c-d", at: str.endIndex)
// after:str.startIndex,在第一个字符的后一位,结果:a666-b-c-d
str.insert(contentsOf: "666", at: str.index(after: str.startIndex))
// before:str.endIndex,在末尾的前一位,也就是最后一个字符的位置插入,从插入位置起,原字符都顺位后移,结果:a666-b-c-888d
str.insert(contentsOf: "888", at: str.index(before: str.endIndex))
// offsetBy:可以指定偏移量,从开始向后偏移3,也就是第三个6的位置,插入后,原字符顺位后移,结果  a66hello6-b-c-888d
str.insert(contentsOf: "hello", at: str.index(str.startIndex, offsetBy: 3))

//删除
//删除第一个'-' 结果:a66hello6b-c-888d
str.remove(at: str.firstIndex(of: "-")!)
//删除所有,符合闭包条件的所有值。结果ahellob-c-888d
str.removeAll { $0 == "6" }

还有其他的关于range的方法,就不在这罗列了,明白了上面这些关于String.Index的使用,其他的基本一样了。

Substring

String可以通过下标、 prefix、 suffix等截取子串,但是子串类型不是String,而是Substring。String本身就是个结构体,不能被继承。Substring也就不是什么子类之类的。他一样也是个结构体。

  • Substring 是字符串的一部分,和父字符串共享同一块内存空间,并且记录了自己的开始和结束位置。
  • String 和 Substring 都声明实现了 StringProtocol。StringProtocol 包含了一个字符串的基本属性和功能。
  • Substring发生修改 或者 转为String时,会分配新的内存存储字符串数据
    具体细节,大家自行Google吧。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容