浅谈队列在移动开发中的应用

恰当的数据结构,能让代码产生质的飞跃。本篇总结下在开发中对‘队列’的一点体会。

有限资源的访问

先进先出(FIFO)是队列的本质属性,所以当遇到这样的需求时,比如实现一个FIFO的cache,那么使用队列自然不需要太多思考。

本篇主要总结下在App中使用队列来控制对‘有限的资源’的访问。

队列在iOS框架中随处可见,比如主线程的runloop会把所有等待处理的Event放在队列里,GCD的serial queue本身就是一个队列,还有NSOperationQueue等。这些例子中有一个共同的模式,就是对一个有限资源的使用,runloop是资源,线程是资源。

而在多线程编程中,我们常常使用锁来控制对资源的访问。从某种角度来看,锁也是操作系统提供的存放访问线程的队列。

道理很简单,更多的时候需要思考的是:什么是有限的资源,什么是资源的访问者。

举一个例子:在iOS中,弹窗(alert view)最多只能显示一个,比如定位城市更新、订单状态改变等。于是我们使用了队列来控制对弹窗的使用(swift伪代码,省略了一些细节):

public class WindowManager {
    private var _queue: Queue<(String, String)>
    private var isShowing: Bool

    public func show(title: String, message: String) {
        onMainQueue {
            if isShowing {
                _queue.enqueue((title, message))
            } else {
                showInternal(title, message)
            }
        }
    }

    public func dismiss() {
        onMainQueue {
            dismissInternal()
            // schedule pending windows
            if _queue is not empty {
                let (title, message) = _queue.dequeue()
                showInternal(title, message)
            }
        }
    }

    private func showInternal(title: String, message: String) {
        isShowing = true
        showAlertView()
    }

    private func dismissInternal() {
        isShowing = false
        dismissAlertView()
    }

    // execute block on main queue
    private func onMainQueue(block: () -> Void) {
        if NSThread.isMainThread() {
            block()
        } else {
            dispatch_async(dispatch_get_main_queue(), block)
        }
    }
}

后来需求变复杂了些,比如当前在登录界面时,弹窗需要等登录界面退出再显示。

Read More

自动状态机

自动状态机是一项非常实用的编程技巧,可以解决一些复杂的逻辑问题,通常来说如果一个系统有多种状态,不同状态之间的切换逻辑不尽相同,那么就可以考虑使用状态机。比如提取字符串的token,网络协议的处理,复杂界面等。

对于状态机的基本定义,在此就不赘述了,可以自行翻阅Wiki.

实现一个自动状态机不是一件很难的事,主要的工作还是在于将实际问题转映射成状态机模型。至于具体的实现方法,有几种固定的模式可循:

Read More

Wordle

记录下自己业余时间在做的一个小项目,这个项目的名字叫PageWordle,可以将网络页面上的文本信息用词云的可视化形式展现,出现频率高的词语将以更大的字体展现,其主要用意是让我们在阅读文章之前可以知道这边文章中的主要概念,再决定要不要继续阅读。

demo

主要流程包括:

Read More

浅谈MVC

MVC(Model View Controller)也被很多人称作Massive View Controller,其原因在于Controller要接纳很多既不属于View,也不属于Model的东西,导致其十分臃肿。而代码一旦变得臃肿,问题就接踵而至,比如难以测试,容易出Bug等等。那么怎样能使Controller不那么臃肿呢,下面就谈一点自己在实际开发中的体会。

View Model

在MVC框架中,Model里面的数据通常需要经过一些处理之后才会在View中展示,比如Model里面的String可能要经过一些格式转换等等操作之后,才可以交给View去展示。这些转换之后的数据不能放在View里面,因为这违背View本身的定义,同时这些数据也不属于Model,那么只能将他们放在Controller里了。

为了将这部分数据从Controller解耦,我们可以在Controller和Model之间添加一层,称之为View Model,如下图:

MVVM

View Model的概念是从MVVM里面来的,大家可以查看这篇文章做更多的了解。

我们在一个项目中使用了这种结构,项目的需求大致是这样子的:

Read More

开篇

2015年决定开始写博客,一来可以锻炼写文档的能力,二来能帮助自己积累技术,督促自己更努力的学习。

作为开篇,分享下自己学习iOS的一些网站和资源吧。

  1. 首先当然是苹果的官方文档和WWDC视频,这个就不多说了。

  2. Cocoa China, 想必做iOS开发的人应该都很熟悉这个网站,内容很广泛,而且经常会翻译一些优秀的英文博文,建议有时间的话可以每天都去浏览有没有新的内容。

  3. objc.io, 这是一个期刊形式的博客,每个月发布一次,每次的内容就集中在某个Topic,内容比较有深度,对iOS技能的提高很有帮助。有中文版的网站:http://www.objccn.io/.

  4. Github Trending, 时常翻阅Github的热门,看别人写的优秀代码,学习别人的软件架构,进步可以非常快。另外也可以跟上最新的技术潮流,这对程序员来说重要性不言而喻。

  5. NSHipster, 关注一些被忽略的Objective-C、Swift、Cocoa特性,每周都会跟新。写文章的是一些比较活跃的开源开发者,包括AFNetworking的创建者Mattt Thompson。这个网站也有对应的中文网站:http://nshipster.cn/.

  6. 念茜的博客, 这是一个非常优秀的关于iOS安全知识的博客,作者是支付宝的iOS安全工程师。对iOS逆向工程感兴趣的同学可以仔细翻阅她的iOS安全攻防系列博文。另外推荐一本关于iOS逆向工程的书,《iOS应用逆向工程:分析与实战》。

  7. 斯坦福大学的iOS教程, 非常适合iOS初学者,这也是公司里新人培训的教程。

  8. 有很多书也是非常不错的,比如《Effective Objective-C 2.0》,《Objective-C高级编程:iOS与OS X多线程和内存管理》等,不过移动领域技术更新比较快,书籍相对滞后,可以作为补充型的学习方式(现在网络上已经到处是Swift了,却很少看到Swift的好书)。

软件开发离不开实践,所以不停的锻炼写代码是提升的必要途径,简言之,学习,实践+总结,持之以恒,你一定可以走的很远。