Dopcn's Blog

life and work

Recent posts

May 24, 2018
我的 iOS 开发之路(一) 入门 iOS 开发需要掌握的东西有三个:一门语言、一个系统 SDK 和一个开发工具 语言 严格来说可以直接与系统 SDK 交互的语言有两个,分别是从最初就一直用的 Objc 和新起之秀 Swift。编程语言本身是一个大领域,聚焦到 iOS 开发特别是入门 iOS 开发,只需要先掌握 Objc 的用法。…
Jun 4, 2017
在 Mac 系统使用launchd运行定时任务 除了工作里,生活中也有很多重复的任务。比如说定期查询户口办理状态,尽可能第一时间去办理下一步。所以需要有一种方法可以定时跑一个脚本去爬取查询网站,解析结果最后通知自己。在 Mac 上可以用 launchd。 在操作系统中除了我们手动打开关闭的应用程序,还有一类后台常驻的进程,叫做 service 或者 daemon,大部分系统服务都是常驻的,在命令行中通过 launchctl list 查看,大部分是以 com.…
Mar 21, 2017
我的 GCD 回顾 入门 GCD 对我来说是初入门 iOS 开发的记忆,那个时候还不知道 UIKit 中的类应该在主线程调用,所以异步获取了数据之后虽然调用了 reloadData,但是界面怎么都不刷新,心慌慌查了好久才解决这个问题,现在回想起来也是蛮有趣。这可以说明 GCD 的引入,真的大大降低了进行多线程操作的门槛,然而要解决多线程带来的难题却依旧不那么容易。…
Feb 19, 2017
我的 Vim 使用日常 原生 vim 需要的配置不少,而且想要有一些特定自动补全需要的配置步骤就更多(iOS API),所以我主要是用 vim mode 插件。几乎主流的 IDE 应该都有 vim 插件,甚至 sublime text 都有 vim mode 可以开启。…
Dec 10, 2015
函数式与过程式编程区别之不同的世界观 大名鼎鼎的 objc.io 有一本书叫做 Functional Swift,只看到这个名字很容易误导人以为 Swift 可以是 Functional 的,但事实上这压根不可能,那本书更准确的名称应该是 Functional part of Swift。一个过程式语言可以拥有函数式的功能,特别是一些比较新的语言 Python Ruby 就曾经因为带有这些功能让人觉得更高级,同时也会被一些人评价说他们只不过实现了一些古老语言早就有的功能。这个评价是客观事实,早期从理论研究中诞生的编程语言大多都很函数式,局部变量和赋值这种过程式的功能仅仅是他们的一小部分。大规模应用于实践之后诞生的编程语言则完全将这一局面翻转了过来,完全是建立在局部变量和赋值之上的过程式,慢慢发展之后才开始增加一些函数式的功能。…
Dec 5, 2015
用高阶函数解八皇后问题 八皇后问题是求在八行八列的国际象棋棋盘上放置八个皇后,令她们彼此之间不能相互被吃的所有方法。国际象棋中皇后可以顺着横竖对角线方向行进任意距离。 高阶函数是泛指那些以一个函数(或者称之为一个过程)作为参数的函数,这个问题里用到的标准库里自带的 map flatmap filter reduce 在函数式编程思路中高阶函数在建立抽象和模块化过程中起到了很重要的作用,以 map 为例它将对一个序列的操作抽象出来,使序列本身和对序列的操作分割开来,这样做的好处是方便重用这种操作,也方便更换序列所需要进行的操作,为了实现这两点在常用的命令式写法中都是要整个操作重写才能完成。 高阶函数的组合使用可以更好的体现模块化的思想,高阶函数本身是模块与模块之间的接口,例如得到一个序列中的偶数的平方的序列:…
Nov 28, 2015
日常生活和编程中的相对关系和绝对关系 这个世界上所有事物都是相对的,只有「相对」本身是绝对的 ——接盘侠日记 最屌文件命名 曾经有一个合作的设计师出了一套新版本界面设计稿,她新建了一个文件夹打包上传到内部 GitLab repo ,我 pull 下来看到这个文件夹 这是我目前看到过最屌的命名,于是我想下一个版本的设计稿文件夹她会起什么名字:「目前最最新的稿子」?「比目前最新的稿子更新的稿子」?「未来最新的稿子」?无论选择这其中的哪一种方案都会有一个共同特点,那就是下一次的起名都必须依赖于这一次的名字,以用来表明这个文件夹更新,而这种依赖是递增不可绕过的,比如说选用第一种方案那么到下下下下个版本就是「目前最最最最最最新的稿子」,以此类推这显然是一个灾难。当然实际中我们的设计师并不会这样,更常见的情况是下一次她的命名直接进入另一个次元,「稿子新」比「目前最新的稿子」更新,这样就可以区分出哪个更新,现在的使用者是清楚了可是接盘侠呢,果然光荣与伟大并不是那么得容易担当。…
Nov 23, 2015
一些有趣的问题在Swift中的表现 1. 排序过的数组遍历更快 实验 let sorted = [false, true] for isSorted in sorted { var datas = Array(count: 32768, repeatedValue: 0).…
Nov 18, 2015
函数式与过程式编程区别之赋值行为 对于常见的过程式编程语言赋值行为和定义变量是同一种形式,都是用等号进行。对于函数式编程语言来说定义和赋值有着显著区别。 由于过程式编程更”容易”进行赋值所以经常采用在整个作用过程中使用起记录作用的状态变量,用一个获取 Fibonacci 前N 项中偶数的函数做示例: func evenFibs1(n: Int) -> Array<Int> { var result = Array<Int>() var x = 0, y = 1, count = n result.…
Nov 13, 2015
复合数据分层设计求数独解的例子 由编程语言自带的数据结构种类有限,在解决实际问题中设计适和的复合数据类型更有利于程序的组织和迭代。复合数据的分层设计一般可以分为三层:最底层是复合数据的实现,上层是复合数据的使用方法,最上层是复合数据使用方法的应用。 在这个例子中,最底层使用数组作为数独数据的实现,在上层使用 struct 的初始化函数、subscript 中的 getter 和 setter,最后基于getter和setter实现数独求解的各个步骤。 enum SudokuError: ErrorType { case initDataError case invalidSudoku case subscriptOutOfRange } struct Sudoku: CustomStringConvertible { private var data = Array<Int>() init(array: Array<Int>) throws { guard array.…