Swift语法从开始到放弃

        突然想到半年没写过东西了,吓得我赶紧抽了根烟,倒了杯水,再放点朱哥走的时候留下的半袋绿茶加了点枸杞(治肾亏不含糖,谁喝谁知道),开始了这篇不知道是啥的写作。

        模仿不侵权吧,这年头搞得什么都侵权,万一涉及侵权什么的联系我啊。---->  鲁迅

        先来几张基本完成版本的新浪微博截图吧,为了少占用服务器空间就随便贴几张吧(这图片为什么不能缩小显示,一排放几张的那种,严重影响美观,差评!)

主页
微博发布
相册浏览

        数据全部来自新浪开放接口,有兴趣想玩玩数据的可以移步--->新浪微博开放平台

        自从苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,就开始了它推广之路,苹果也是将Swift作为主推语言供开发者学习,OC的地位也是从前三慢慢的下降到了十几名的位置,而Swift呢,从一开始的火热,到现在的不温不火。不过不得不承认的是它这种语言确实像苹果说的,简洁易学,在每次版本更新的时候都会将一些累赘的语法删除,保留最需要,最能理解,最简洁的语法。自从接触到Swift之后,慢慢的开始写了写,它的简洁的语法确实是可以减少很多的重复工作,包括一些对其他语法的引用,你可以从它里面看到java,C++, php, javaScript等等语言的影子。关于它的介绍可以移步百度百科--->Swift介绍

        说说完成的这个程序吧。当然我在这个程序中仅仅是做了个数据的展示,至于真实环境用户的数据缓存等等一些其他的技术,就略过了,这要讨论可能一时半会也写不完。

         有关这个程序我是从Swift1.0追随到Swift4.0的,基本都是在业余时间完成的,当然其中一段时间懒的写了就放下了,每次发布新版本又心动了就开始继续完善。对于每次版本更新语法的改变,给我的感受完全可以用红楼梦开篇的一句话来形容(这TM是啥):

满纸荒唐言,一把辛酸泪

        整个程序的备份工作以及代码的提交都是在github上的,关于github上个人代码仓库的建立,有不知道的请移步我的博客-->github上建立个人代码仓库

        为什么我项目中没有用Swift去写?

        第一:虽说Swift和OC是完全兼容的,那么也就是说项目可以混编,这个没有错,但是现有的框架如果用Swift去写,很多现成的东西有可能都得用Swift一行一行的去写,这就避免不了的需要在项目中拉入很多新的基本和OC功能一模一样的框架,这样就造成了框架的重复,本来一行代码可以实现的问题在Swift中要写很多,那么本来应该很简单的语言变成了一种负担,总给人一种不伦不类的感觉。

        第二:项目的维护,毕竟项目不是一个人在写,对于新语言理解大家也都不一样,可能在这里要用这种思维去理解突然在那里要用到另一种思维,在找问题的时候也感觉比较麻烦。

        第三:新语法的变化,我是跟随着这个语言一直写过来的,到现在基本趋于稳定,但是每次更新一些新的语法的变化实在是让人头疼,尤其是2.0到3.0的迁移工作,那真是简直了,虽说现在稳定了,但是保不齐突然又来个突发奇想什么的大改一下语法也是有可能的,说实话它的实用性还有待考证(不过我新建项目写起来确实爽)。我看见群里曾有人说他学了四门语言,哈哈,这个倒是真的,亲身体会。写Alamofire请求框架以及一些其他框架的大神也是被苹果折腾的够呛,不过折腾归折腾,每次语言变化的一些微小细节都能从里面感受出来,就在前两天发布4.0的时候一个突如其来的崩溃整的我都想删了整个项目。

       第四:项目的兼容,Swift中有很多语法基本都是从8.0开始的,有些语法还是8.0以后的,现在项目的支持程度不够。

       当然,都是我自己的想法,不喜勿喷。


        说了这么多废话,开始进入正题吧。我写这个文章的目的,是把我在从Swift1.0到Swift4.0当中更新遇到的问题,以及一些我认为比OC新颖的语法顺便做一下笔记。当然记忆力不是很好,毕竟跨度有点大,可能很多语法的变化在改完每条红杠以后都忘了,我尽量写的详细一点。写了这么多我感觉此处应该有图,那就贴两张从开始到放弃的提交图吧:

项目开始
最后提交(放弃)

       这只是从开始到结束的一小部分的提交记录,关于这两张图大家都懂,不做过多的解释了。

        那就从项目的搭建开始吧。至于我写的是啥, 看不下去的请移步---->戳我有惊喜(广告费记得给我)。

        新浪微博登录的授权模式:采用OAuth2.0的授权方式(很多第三方登录的提供的接口都是采用这种授权方式,包括微信支付宝),关于OAuth2.0的授权自行移步百度(当然第三方个网站文档也有很详细的介绍)。

        提到登录这里提一下字符串的截取方法,这个也是从2.0到3.0变化挺大的一个地方,

字符串截取

OC中字符串的截取:

NSString *string2 = [string1 substringFromIndex:i];

NSString *string3 = [string2 substringToIndex:11];

Swift对于字符串截取进行了一个简化,我们可以直接指定从开始到结束的范围:比如在OAuth2.0授权中用到的,从query中截取授权码:

let code = query[query.index(query.startIndex, offsetBy: 5)..<query.endIndex];

由于Swift是强类型推断语言,所以对于可选的值我们需要进行解包,另外它的判断条件可以是多个条件并列的,我记得在2.0中还可以添加where关键字的限制,在3.0中移除了这个操作,还是以query值作为可选为例:

if let query = request.url?.query, query.hasPrefix("code=") {

// 这里的query为解包后的值,真实存在的可以直接使用

} else {

// 异常处理

}

对于判断Swift还加入了新的语法guard(判断与if正好相反):

guard let img = image else {

print("1张图片缓存图片为空")

}


字符串的拼接

OC中可以直接使用:

1. string = [string1 stringByAppendingString:string2];

2.string = [NSString initWithFormat:@"%@,%@", string1, string2 ];

3.string = [string stringByAppendingFormat:@"%@,%@",string1, string2];

Swift中虽然提供了这些方法但是使用起来比较麻烦,它给我们提供了类似JAVA中的字符串拼接方法:

let sting = string1 + string2

或者插值语法

let sting = "\(string1) + \(string2)"

代码块

说起请求,就不得不提到网络延时的问题,在3.0中对于GCD有了更大的改进:

我们在OC中的延时代码(用C语言的函数实现):

// 任务放到哪个队列中执行

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

doubledelay =3;// 延迟多少秒

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay* NSEC_PER_SEC)), queue, ^{

// 3秒后需要执行的任务

});

在Swift改进中变得更加面向对象:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(1 * Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC), execute: {

self.close()

})

说起代码块 ,对于类中我们引用的对象直接可以用函数名或者变量名去引用,然而在代码块中引用就必须使用self才能调用,在2.0中写入代码块的函数都是无法提示打出来的,这一点在3.0中有了改进。

我们在OC中所说的代码块在Swift中似乎有了新的代言,称为闭包。闭包苹果在3.0中加入了逃逸闭包和非逃逸闭包的区别。

函数的使用:

关于基本函数的创建使用可以移步我的博客:Swift基本函数的使用

在函数的调用上面与OC最大的不同点在于链式函数的使用,在Swift中你可以将有因果关系的一堆函数一直用 . 链接下去,直到返回你想要的值,这样做可以最直观的感受就是可以将有关系的一组函数组合在一起,找问题也不想OC中那样跳来跳去,这种使用类似最近比较火的ReactiveCocoa

在3.0中对于有返回值得函数可以使用"_"接收来忽略返回值,不然会报警告,当然警告也可以通过在返回的函数上面使用@discardableResult关键字来忽略警告。

既然文件之间的函数可以相互调用,那么就存在文件函数错用的问题,Swift也为我们提供了函数范围的限制,2.0中一直是使用private、public关键字限制,不过在3.0对于private、public的定义有了新的含义,它在这两个关键字的基础上又提供了两个新的关键字:fileprivate、open

于是在同一个文件里面不同的类定义的函数只要定义为private就不能相互引用,就连扩展也不能引用,扩展中要引用就要将属性或者函数定义为fileprivate,关于这几个关键字的细节介绍可以移步----->关键字的限制

扩展

不得不说这是个很好用的东西,以前我们在OC一个类里面的写的东西甚至挖空了心思想把它移出去,现在在Swift中我们可以使用extension轻松将这些东西移出去,将同类东西归类比如我们经常用到的一些代理代码:

extension PhotoBrowserCollectionViewCell: UIScrollViewDelegate {

func viewForZooming(in scrollView: UIScrollView) -> UIView? {

return imageView

}

当然它的更强大的使用不仅仅限于此,项目中用到的就是这个地方了。


约束(当然可视化视图就不需要考虑这些了)

我们经常在代码中写约束用到一些框架就可以轻松实现,但是它底层苹果为我们提供的代码却相当烦躁,这个确实不太友好

比如我们对于一个视图的约束:

//        indicator.translatesAutoresizingMaskIntoConstraints = false

//        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.centerX, multiplier: 1.0, constant: 0))

//        contentView.addConstraint(NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.centerY, multiplier: 1.0, constant: 0))

而框架为我们提供的解决方案:

indicator.snp.makeConstraints { (make) in

make.centerX.centerY.equalTo(contentView)

}

相比较相当简单,说到约束提一下VFL(可视化格式语言):

我们要约束一个视图可以用

maskIconView.translatesAutoresizingMaskIntoConstraints = false

addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["subview": maskIconView]))

addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-(-35)-[regButton]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["subview": maskIconView, "regButton": registerButton]))

其实这些框架的底层基本都是用这些东西实现的,不过框架开发者为我们提供了比较友好的接口而已。

遍历

起初在1.0的时候我们可以直接使用C语言的for循环遍历,但是在后来3.0的时候直接改掉了这个使用方法,我们可以用这样的方法遍历:

for dict in array {

list.append(Status(dict: dict))

}

for _ 0..<10 {}

还有更简洁的语法:

array.forEach({ (dict) in })

(0..<10000).forEach { (i) in }

三目运算符

在3.0中加入的新语法中有个"??"语法,这个也是借鉴C++的语法。使用相当方便。

比如:

let count = status?.pictureURLs?.count ?? 0

枚举

不得不说这个在Swift中确实是个突破,在OC中我们只能定义用C风格,枚举值一般是4个字节的int值,在64位系统上是8个字节。

而在Swift中打破了这个常规,比如我们可以定义string类型的枚举,而且我们在枚举中还可以使用函数:

enum StatusCellIdentifier: String {

case NormalCell =  "NormalCell"

case ForwardCell = "ForwardCell"

/// 静态函数,根据微博数据返回对应的标示符

static func cellId(status: Status) -> String {

return status.retweeted_status == nil ?

StatusCellIdentifier.NormalCell.rawValue :

StatusCellIdentifier.ForwardCell.rawValue

}

数据刷新

在我们项目中通常会用到一些第三方框架去处理数据的刷新问题,不过苹果为我们提供了原生的刷新控件:UIRefreshControl,说一下原理吧,API提供给我们的方法不多也就几个。

一般刷新采用kvo监听视图frame的变化,就像这样:

self.addObserver(self, forKeyPath: "frame", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)

然后我们会根据frame的变化做一下我们想要的操作(这里通常我们会指定一个偏移量作为基准,然后判断和这个偏移量的大小做相应的操作):

向下拉y值越来越小,向上推y越来越大

从表格顶部向下拉,y是负数

拽到一定幅度,会自动进入刷新状态

字典转模型

这里比较特殊的是int类型,int类型在字典转模型的时候必须为不可选的必须赋予初始值与oc不同在于数组中加入数据更加简单。

结构体属性

在OC中我们修改结构体属性会像这样:

CGRect btnF = self.btn.frame;

btnF.size.height += 40;

self.btn.frame =  btnF;

后来我们引入了分类可以直接修改属性,而Swift中我们可以直接修改:

s.height = 0.6 * s.height

导航栏

关于导航栏这个问题吧,每次苹果发布大的版本都会把它的结构改一遍,当然每次大版本发布我都要跟着改一遍这些特殊的页面,也许有它的考虑吧,毕竟这个东西应该是越写越好的(暂时这样认为),但是我想说的是fuck your sister

协议

有人称这个语言为面向协议的编程语言,目前使用到的协议仅仅限于常用的协议的使用,一些高大上的用法还在学习中。。。。


目前和其他不一样的地方能相当的就这些了,以后想到继续更新吧。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,080评论 4 62
  • 转载自:https://github.com/Tim9Liu9/TimLiu-iOS[https://github...
    香橙柚子阅读 8,516评论 0 35
  • 嗯哼嗯哼蹦擦擦~~~ 转载自:https://github.com/Tim9Liu9/TimLiu-iOS 目录 ...
    philiha阅读 4,864评论 0 6
  • No matter the ending is perfect or not, you cannot disapp...
    雨潇傾寒阅读 227评论 2 0
  • 大一就已接近尾声,此时此刻的我,我不知道适不适合写点东西,因为我刚喝的有点高,脑子不是那么清醒,不知道是不是因为喝...
    繁华落尽倾城泪阅读 699评论 0 2