0%

异步事件编程,其实并不是什么新东西了,基本所有涉及到GUI的,网络请求的,数据库读写的,都会有它的身影。

异步事件,就是说这一个代码或者代码块,并不会阻塞程序的运行,程序会立即执行下一条语句,而这条语句,会在相应的方法调用结束之后,执行它自身的回调函数发送一些信号,来表明这个异步事件完成。就像你约会提前1小时到见面地点,先去买点东西踩点什么的(……),等GF/BF到了之后短信通知你,你就立即回来。而不是一直在原地等到对方过来(……)

最早使用异步开发,是在使用JavaScript来开发Web前端的时候,XMLHttpRequest或者jQuery的**$.ajax**中,都会用到回调函数,来指明成功或者失败之后的处理方法。当对应的网络请求得到响应之后,会调用响应的成功或者失败的回调函数,然后执行里面相应的方法,这大大提升了前端的效率,不会在网络请求时整个页面卡住,而且也不需要一次次轮询看是否有响应,简化了代码的复杂性。

这点Node.js中更为常见,不过也更能表现中滥用异步事件编程的问题。新人使用Node.js总会发现基本任何东西都是异步的,数据库是异步的,IO文件操作是异步的,Session读写是异步的,甚至获得Request对象都是异步的。这就导致很多人一直在嵌套回调函数,导致了著名的Callback Hell

在Node.js中,解决方案有非常成熟的Async,更有号称能用同步思维写异步的Promises,都是非常棒的解决方案。前者的本质就是一个自动生成回调的封装……,后者则是一个真正意义上的全新的解决方案。

而在Swift和iOS开发中,也有必须用到异步事件编程的地方。除了View层的简单UI和Controller之间的交互以外(这部分一般不需要手写代码处理异步交互或者顺序),其他很多地方需要这些知识。例如网络请求的异步调用,请求队列的处理(虽然可以一个网络请求就是一个线程,但这种方法的效率不高,而且容易导致线程间冲突),SQLite数据库大量数据的读写,本地存储的大量数据读写,复杂UI的渲染顺序等等……这些都是需要进行异步编程的,而不能让同步的代码阻塞住整个应用或者UI。

阅读全文 »

iOS开发UI一直是一个问题,当年用代码画UI一度成为流行趋势,相信代码能万能解决问题,而且十分简单。

然而,现在由于iOS设备的不断迭代,市场上常见的iPhone设备就会有:

  1. iPhone4/4S 960640 (480320 @2x)

  2. iPhone5/5S 1136640 (568320 @2x)

  3. iPhone6 1334*750(667*375 @2x)

  4. iPhone6 Plus 1920*1080(736*414 @3x)->(2208*1242)

加上iPad以后,还会有一个1024768(@1x) 和 20481536(@2x) 原来想要做一个自适应的,同时支持iPhone和iPad的应用,就算用代码来画UI,也是十分简单的。而现在,在这总共3类,5种,7状态的iOS设备面前,就会有点力不从心了,更别说以后想要做WatchOS的开发就会遇到很多问题,而Autolayout的解决方法的提出大大简化了这一过程

Autolayout,就是通过一系列的约束条件来控制一个UIView在视图中的位置,同时还要配合Size Classes(兼容iOS8之后的设备)

1、对于一个TableView,我们只需要设置它的Leading、Trailing、Top、Bottom临接到根View即可让它永远全屏显示,无论设备像素。而且,重要的一点,就是在Attribute Inspector中,要把这些距离设置为Standard(或者是0),这样才能在不同设备中获得推荐的显示效果(如果不是Standard或者0的话,就要小心了,这些就是所谓的魔法数字,很可能不同尺寸设备上显示效果会有所差别)

阅读全文 »

这一次主要讲讲代理(Delegate)在iOS开发中的重要意义

上一次说道通过一个类的静态方法来把所有的垃圾初始化代码扔到一起,减少每次创建新的VC所带来的重复劳动问题,这次主要说一下如果通过代理,来使你的代码更为简单,调用一个API: “Could not be simple”

所谓的代理,就是意思被代理的类把自己的方法交给代理人那个类来执行

首先,为了做一个代理,你必须要定义一个协议(称作APIGetter),这里我是把所有的返回结果放在代理,发送请求通过类的静态方法来使用(类名就叫做HeraldAPI吧~)

协议:

1
2
3
4
@objc protocol APIGetter{
func getResult(APIName:String, results:NSDictionary)
func getError(APIName:String, statusCode:Int)
}
阅读全文 »

iOS开发中,如果不进行适当的封装,使用协议或者继承类来进行开发,你就会遇到传说中的ViewController(以后简称VC) Hell的问题……

比如说,我们先声网App中为了调用接口,做简单的判断,会有如下的垃圾代码(前辈遗留下来的):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
override func viewDidLoad() {
super.viewDidLoad()

var color = UIColor(red: 153/255, green: 204/255, blue: 204/255, alpha: 1)
self.navigationController?.navigationBar.barTintColor = color

self.httpController.delegate = self

Config.shareInstance().isNetworkRunning = CheckNetwork.doesExistenceNetwork()

if Config.UUID == nil || Config.UUID!.isEmpty
{
Tool.showErrorHUD("去信息门户登录一下吧:)")
}
else if !Config.shareInstance().isNetworkRunning
{
Tool.showErrorHUD("貌似你没有联网哦")
}
else
{
Tool.showProgressHUD("正在更新校园网信息")
sendNicAPI()
}
// Do any additional setup after loading the view.
}

func sendNicAPI(){
let nicURL = "http://herald.seu.edu.cn/api/nic"
let parameter:NSDictionary = ["uuid":Config.UUID!]

self.httpController.postToURLAF(nicURL, parameter: parameter, tag: "nic")
}

func didReceiveDicResults(results: NSDictionary, tag: String) {
if let content:NSDictionary = results["content"] as? NSDictionary{
if tag == "nic"{
firstSend = false
Tool.showSuccessHUD("获取信息成功")
println(content.allKeys)
}
}
}

看到了吗,每个VC开头都得这样写一发,如果我们有20多个功能呢?会变成什么样子?

所以,这样下去是绝对不行的,必须对整个乱七八糟的初始化,发送请求,请求接受进行封装,这里就会用到Swift最有用的协议,代理,以及闭包了。

阅读全文 »

终于,我参加的第三个Web项目基本已经完成了Beta版本的整体架构和实现。

这次的Web项目要求,是制作一个基于Web(或者移动Web)的在线协作编辑平台,主要支持Markdown语法及同步预览,类似于Google Docs或者Office Online这样的东西(但是绝对不可能达到国际一流大厂的水平)

由于只有我们4个人开发(其中2个还算专门前端开发),所以尽可能减少后端开发压力,经过初步的讨论,最终选择了使用Node.js作为后端开发语言。Node.js强力的非阻塞IO和异步事件非常适合我们这种IO密集型的应用。而对于协作的部分,我们选择使用socket.io来进行这种密集文本数据的通信和广播,也能很大的减少开发周期。

嘛,整体架构大概这样,虽然很丑陋,对于我这种没有实际架构Web经验以及Beta版来说,已经足够了。

话不多说,作为一个多人编辑的平台,首先就需要传统的Web应用的老三样:用户管理,文档管理,项目管理,今天就主要说这些。

阅读全文 »

一年一度的圣诞节又到了……或许这又意味这一年的开始了。

这一年中,有很多人给了我帮助,有欢乐之时,也有低落之时。曾经以为自己能够找到自己的目标,却发现自己还是原地踏步。希望来年之时,心中这份迷茫能够或许减少一分吧。

感慨就到这里,希望在这个圣诞日子中,你我能够忘却烦恼,睁开眼睛发现属于自己的幸福,勇于追求自己的未来,不要被周遭而所困扰。

最后,谨祝愿:

自己能够追寻自己的梦想,看到这的你能够拥抱自己的幸福与喜悦。

最后,献上我的圣诞贺卡~

阅读全文 »

说来也是惭愧,从大一暑假接触到第一门Web后端语言——PHP之后,自己对Web应用程序的认识却一直没有多大改变,对整个Web服务器的运行也没有清晰的概念。不过,这个大二的寒假里面,由于需要架设一个Web多人协作编辑平台,我接触到了这个非常热门尽管国内应用不多的后端架设方式——Node.js

说到Node.js,其实很多人也都知道,一个JavaScript在本地的运行时,基于Google的V8引擎。很可惜,由于自己当时学习Web主要走的后端路线,自己对JavaScript的认识也就靠的是w3school的简单说明和了解以及简单的jQuery用法罢了。学Node.js对我印象最大的,就是事件驱动的回调函数。(其实还是与自己并未真正接触到函数式编程有关)

举个例子,就是最简单的Hello World Web应用程序。

1
2
3
4
5
6
7
var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

在JavaScript里面,函数是和变量同地位的一等公民,它可以被传递进当为参数,这种写法初次接触JavaScript的人肯定感觉非常不适应(尤其从Java,PHP转来的),不过习惯之后便发现这样带来了不错的易读性。这里面,那个匿名函数function(request,response)就是一个回调函数,Node.js内置的http对象通过listen进行8888端口的监听,一旦有任何访问便会调用这个回调函数,执行那三行来发送一个Hello World的HTML文本回去

Node.js编写Web程序的体验绝对是Java和PHP很难达到的,因为你不仅要写一个Web应用程序,必须自己写一个HTTP服务器程序。不过这也意味着你可以干更多的事而不用局限于PHP这种解释器一样执行的代码,很多人甚至不知道在一行简单的echo “Hello World!” 的背后的Web应用程序究竟是怎样工作的,你也可以不用再和Apache,Nginx这种Web应用程序的使用打交道,你可以自己写一个类似的出来,定制化更高。   上面关于Node.js的简单认识也就先这样,下面我想说说关于Web应用程序的非常简单的架构组织。

阅读全文 »