A. Web前端开发与iOS终端开发的异同
语言
前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,不像后台想用什么就用什么,iOS只能用Objective-C,前端只能javascript,当然iOS还可以用RubyMotion,前端还能用GWT/CoffieScript,但不是主流,用的人很少,真正用了也会多出很多麻烦。
这两者有个有意思的对比:变量/方法命名的风格正好相反。苹果一直鼓吹用户体验,写代码也不例外,程序命名都是用英文全称并且要多详细有多详细,力求看变量和方法名就能知道是干嘛的,例如application:didFinishLaunchingWithOptions:。而js因为每次都要从网络下载,要力求减少代码体积,所以变量方法名是尽量用缩写,实际上有代码压缩工具,无论变量名写多长最终上线的效果是一样的,但大家也都习惯了用短的命名,例如上述objc的application:didFinishLaunchingWithOptions:方法在js里习惯的命名是:$()。
objc与js都是动态语言,使用起来还蛮像,但objc是编译型,速度快,很多错误也能在编译过程中被发现,js是解释型,性能依赖于解释引擎,即使在强劲的v8引擎下性能也赶不上编译型语言,语言太动态,变量完全没有类型,写起来爽,debug起来稍微费点劲。一直感觉js轻巧灵活放荡不羁充满各种奇技淫巧,objc中规中矩没c++ java那么严肃也没有js那么灵活。
线程
前端开发几乎不需要线程这个概念,浏览器实现上页面HTML和CSS解析渲染可能与js不在同一个线程,但所有js代码只执行在一条线程上,不会并发执行,也就不需要考虑各种并发编程的问题。在新的JS特性中可以创建worker任务,这样的任务是可以另起一条线程并行执行的,但由于并不是所有浏览器都支持,不同线程传递数据各个标准定的还不一样,使用场景也少,似乎没有大规模用起来。对于数据库操作/发送网络请求这样的任务是在不同于js代码执行线程的,不过这些都由浏览器管理,前端无需关心也无法影响这些线程,只需接收事件回调,不需要处理任何并发问题。
终端开发需要大量使用多线程,iOS有一条主线程,UI渲染都在这个线程,其他耗时长的逻辑或者数据库IO/网络请求都需要自己另开线程执行,否则会占用主线程的时间,导致界面无法响应用户交互事件,或者渲染慢导致滚动卡顿。程序逻辑分布在多个线程里跑,需要处理好各种代码并发执行可能带来的数据不一致/时序错乱之类的问题,并发也导致有些bug难以排查,一不留神就掉坑,需要适当用一些队列/锁保证程序的执行顺序。iOS提供了一套多线程管理的方法GCD,已经把线程和队列封装得非常简单易用功能强大,比其他端或后台是好很多了,但还是会花大量功夫在处理多线程问题上。
存储
终端开发需要大量的数据存储逻辑,手机APP不像浏览器,用户打开浏览器必定是连着网,但打开一个APP时很可能是离线,也很可能处于网络状况极差的移动GPRS,所以必须把之前请求回来的数据保存好。保存数据后又需要与服务端最新的数据同步,如果全量同步数据量太大,耗流量速度也慢,于是需要增量同步,需要与服务端一起制定实现增量数据返回的方案,需要处理好客户端与服务端数据一致性的问题。当数据存储量大结构复杂时,还需要利用好有限的内存做cache,优化各类存储查询性能。
前端在桌面端很少需要存储,除非是Single Page App,不存储自然就不需要数据更新的一系列工作,数据都是从后台取出拼接后直接显示到页面上,即使像微博有可以在页面内不断加载更多数据,数据也只存在于内存,不会持久化存储,因为桌面端网速稳定,不计流量,所有数据可以直接从后端拿取,客户端没必要再做一套存储。移动端那些做得很像原生APP的Web应用就跟终端开发一样了,数据同样保存到SQLite,存储逻辑以及要处理的问题都差不多。
框架
在第三方框架上Web前端和iOS开发完全相反,Web原生弱小又十分开放,让大量第三方框架和类库可以施展拳脚,而iOS原生强大又十分封闭,导致第三方框架没有多少生存空间。
浏览器一开始只为内容型的网页而设计,js也只是这个网页上能加点小特效的脚本语言,在Web应用时代跟不上发展,需要很多第三方库和框架辅助,再加上前端开发是完全开放的领域,导致库和框架百花齐放多如牛毛,在初期多数库的作用集中在封装dom操作,大家不断重复造dom操作基础库的轮子,在一段时间百家争鸣后独尊jQuery,在有使用库的网站中90%以上使用jq,几乎成了个标准基础库。后期大家已经不再重复造这个基础库的轮子了,多了一些代码组织和前端架构的框架,例如一些帮助项目模块化的框架require.js,MVC框架backbone/angular.js等。
iOS开发苹果已提供了完整的开发框架cocoa,而这框架在每一代系统中都在升级优化和添砖加瓦,开发模式也已经定型,第三方框架没有多少生存空间,大量流行的开源项目是一些通用组件和库,像网络请求库AFNetworking,数据库操作库FMDB。而一些大的框架像beeFramework/ReactiveCocoa较难流行起来。
兼容
前端开发需要兼容大——量的浏览器,桌面的chrome,safari,ie6-ie10,firefox,以及各种套壳猎豹360等浏览器,移动端iOS/Android各自的浏览器,以及无限的不同的屏幕尺寸。看起来挺可怕,实际上也没那么难搞,只是拿出来吓唬下人。桌面端chrome/safari以及各种套壳的极速模式用的都是Webkit,差异很小,firefox也大体遵从标准实现,与Webkit差别不大,旧的ie6/7就需要特别照顾,不过很多网站都不支持ie6了,移动端更是一家亲,全是Webkit,除了新特性上的支持程度不一,其他差异不大。对于不同的屏幕尺寸,高端点的会用响应式布局,针对不同屏幕尺寸自适应到不同布局,一般点的桌面端定死宽度,移动端拉伸自适应宽度就搞定。
终端开发也需要兼容各种不同的系统版本和手机尺寸,Android不用说,iOS也有3.5/4/4.7/5.5/9.7英寸这些尺寸,不过兼容起来跟Web一样挺容易,就是自适应宽度,iOS的UIKit把这些都处理好了,还有autolayout,sizeClass等高级特性可用,在尺寸上并不用花太多功夫。系统版本上iOS7为分水岭,iOS7前后版本UI上差异比较大,需要做一些功夫兼容,不过iOS用户更新换代很快,预计再过一两年iOS7以下用户就可以忽略了。
性能
终端和前端都是面向用户的,性能优化目的都是尽快呈现内容,以及让程序在用户操作下流畅运行。终端主要关注的是存储/渲染性能。当一个APP存储数据量大,数据关系复杂时,数据查询很容易成为性能瓶颈,需要不断优化数据存取的效率,规划数据IO线程,设计内存cache,利用好终端设备有限的内存,渲染上避免重复渲染,尽可能复用视图,寻找最高效的渲染方案。
前端关注页面加载速度,由于Web页面的结构/样式/程序/资源图片都是实时请求的,要让页面更快呈现内容,就要优化这些请求,让这些资源以最快速度加载下来,包括合并图片/合并代码减少请求数,压缩代码,并行请求,根据版本号缓存代码请求,gzip压缩,模块/图片懒加载等。此外跟终端一样也关注渲染性能,遵从一些规则避免页面reflow,避免使用CSS阴影这样耗性能的特效,用CSS3动画代替js等。
编译
终端开发需要编译的过程,把程序编译成机器语言,再与各种库链接后生成平台对应的可执行文件,最后由操作系统调度执行。在iOS终端开发中编译和链接的规则苹果已经在xcode这个开发工具上封装好,一般开发可以不用关心,但有深层需求时还是需要跟编译打很多交道,例如用编译前端Clang自定义静态代码检测规则,写编译脚本做自动化编译和持续集成,打包生成静态库,根据链接后的可执行文件的组成优化APP体积等。
前端开发的程序则不需要编译过程,只需要把代码扔给浏览器,浏览器边解析代码边执行。虽然js/css代码写完无需做任何事情浏览器就可以解析执行,但为了上面说的性能优化,前端代码上线前会对所有代码和资源文件进行处理,这些处理包括:压缩合并js/css,合并css sprite图,处理模块依赖,处理代码资源版本号,处理资源定位等。这个过程很像传统程序的编译,把给人看的代码优化处理成给机器看的,并解决一些依赖关系,可以算是前端的编译过程。像grunt.js/fis这些工具可以帮助完成这个编译过程,通常前端编译跟上线部署结合在一起,作为上线系统的一部分。
安全
前端和终端的安全性问题上虽然不需要像后端考虑得那么多,但还是有些需要注意。在请求的安全上,终端和前端都一样,用户向后端发送的请求都需要经过层层路由,不知道在哪里就被截获篡改或回放了,于是需要做一些措施防御这些情况,最常见的就是身份验证,多是采用会过期的token形式代替用户名密码,防止被抓包后黑客可以永远登陆这个账号。数据安全要求高的会用加密传输,或者使用https,另外还需要看情况处理一些DNS劫持,运营商广告植入等问题。
其他安全问题终端很少考虑,在未越狱的iOS机器上系统已经帮忙保证了整个APP运行环境的安全,而在越狱的机器下恶意程序拥有root权限可以做任何事情,APP也难以防范。前端方面浏览器的特性使前端开发有几个安全隐患,一是Web页面上任意位置都可以动态插入js代码,浏览器会无区别地执行这些代码,二是身份验证信息都统一保存在cookie里,三是页面上可以随意通过iframe嵌入其他网站的页面。造成XSS、CSRF、cookie劫持这些攻击手段,所以前端写代码时都需要考虑还这些安全问题,做好相应的防范,最简单和重要的防范就是对所有用户输入输出的内容做完整的过滤,避免页面内被嵌入恶意代码。
交互/开发
最后说下对这两个领域在交互和开发上的个人感触。以前在做Web前端时,感觉Web让人机交互倒退了十年,交互都是硬邦邦的点击—啪一下出来结果,滚动是一格格地刷新,很多人当时在鼓吹html5可以做出多么炫的效果时,实际上FLASH在十年前就可以做出来了,还比最现代的浏览器更流畅。iPhone流行后,人机交互终于恢复了应有的水平,体验上比Web流畅太多,指尖交互/流畅的动画/便捷的滑动手势/无限制的实现,主流终于恢复或超越了十年前Flash的水平。
但人机交互提升了,开发方式却大倒退,Web的开发方式非常先进,用户用到的都是最新版本,发现bug可以马上上线秒修复,特别适用于互联网环境下的快速迭代,而终端APP不行,撇开iPhone的审核不说,Android也无法做到保证用户用的是最新的程序,用的都是传统的客户端更新的方式,bug的修复版无法及时给到用户,无法一天上线几十次,需要维护很多旧版本,开发方式倒退回Web时代以前。这都是因为移动网络不稳定以及流量有限造成的,移动端无法像桌面端浏览器那样完全依赖网络,所以在移动网络稳定流量免费之前,开发方式都不会有多大变化。
另外并不看好HTML5,网络上说它可以取代APP说了三四年,到现在也没什么战绩,我看不到它的优势,原生APP可以获得更多的系统资源,更流畅的人机交互体验,HTML5在这方面永远比不上,而它在移动端网络和流量的限制下也无法发挥Web的开发优势,所以它不会成为主流,只适合做一些轻量的小东西。
B. Java并发编程(二)为什么需要多线程
*使用线程可以把占据时间长的程序中的任务放到后台去处理
*程序的运行速度可能加快
*在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等等。
*多线程技术在IOS软件开发中也有举足轻重的位置。
C. 如何设置两个方法之间的依赖关系 ios
iOS Concurrency Programming Guide
iOS 和 Mac OS 传统的并发编程模型是线程,不过线程模型伸缩性不强,而且编写正确的线程代码也不容易。Mac OS 和 iOS 采取 asynchronous design approach 来解决并发的问题。
引入的异步技术有两个:
Grand Central Dispatch:系统管理线程,你不需要编写线程代码。只需定义想要执行的任务,然后添加到适当的dispatch queue。Grand Central Dispatch会负责创建线程和调度你的任务。系统直接提供线程管理,比应用实现更加高效。
Operation Queue:Objective-C对象,类似于dispatch queue。你定义想要执行的任务,并添加任务到operation queue,后者负责调度和执行这些任务。和Grand Central Dispatch一样,Operation Queue也管理了线程,更加高效。
Dispatch Queue
基于C的执行自定义任务机制。dispatch queue按先进先出的顺序,串行或并发地执行任务。serial dispaptch queue一次只能执行一个任务,直到当前任务完成才开始出列并启动下一个任务。而concurrent dispatch queue则尽可能多地启动任务并发执行。
优点:
直观而简单的编程接口
提供自动和整体的线程池管理
提供汇编级调优的速度
更加高效地使用内存
不会trap内核under load
异步分派任务到dispatch queue不会导致queue死锁
伸缩性强
serial dispatch queue比锁和其它同步原语更加高效
Dispatch Sources
Dispatch Sources 是基于C的系统事件异步处理机制。一个Dispatch Source封装了一个特定类型的系统事件,当事件发生时提交一个特定的block对象或函数到dispatch queue。
你可以使用Dispatch Sources监控以下类型的系统事件:
定时器
信号处理器
描述符相关的事件
进程相关的事件
Mach port事件
你触发的自定义事件
Operation Queues
Operation Queues是Cocoa版本的并发dispatch queue,由 NSOperationQueue 类实现。dispatch queue总是按先进先出的顺序执行任务,而 Operation Queues 在确定任务执行顺序时,还会考虑其它因素。最主要的一个因素是指定任务是否依赖于另一个任务的完成。你在定义任务时配置依赖性,从而创建复杂的任务执行顺序图。
提交到Operation Queues的任务必须是 NSOperation 对象,operation object封装了你要执行的工作,以及所需的所有数据。由于 NSOperation 是一个抽象基类,通常你需要实现一个自定义子类来执行任务。不过Foundation framework自带了一些具体子类,你可以创建并执行相关的任务。
Operation objects会产生key-value observing(KVO)通知,对于监控任务的进程非常有用。虽然operation queue总是并发地执行任务,你可以使用依赖,在需要时确保顺序执行。
异步设计技术
通过确保主线程自由响应用户事件,并发可以很好地提高应用的响应性。通过将工作分配到多核,还能提高应用处理的性能。但是并发也带来一定的额外开销,并且使代码更加复杂,更难编写和调试代码。
因此在应用设计阶段,就应该考虑并发,设计应用需要执行的任务,及任务所需的数据结构。
Operation Queues
基于Objective-C,因此基于Cocoa的应用通常会使用Operation Queues
Operation Objects
operation object 是 NSOperation 类的实例,封装了应用需要执行的任务,和执行任务所需的数据。NSOperation 本身是抽象基类,我们必须实现子类。Foundation framework提供了两个具体子类,你可以直接使用:
类 描述
NSInvocationOperation 可以直接使用的类,基于应用的一个对象和selector来创建operation object。如果你已经有现有的方法来执行需要的任务,就可以使用这个类。
NSBlockOperation 可以直接使用的类,用来并发地执行一个或多个block对象。operation object使用“组”的语义来执行多个block对象,所有相关的block都执行完成之后,operation object才算完成。
NSOperation 基类,用来自定义子类operation object。继承NSOperation可以完全控制operation object的实现,包括修改操作执行和状态报告的方式。
所有operation objects都支持以下关键特性:
支持建立基于图的operation objects依赖。可以阻止某个operation运行,直到它依赖的所有operation都已经完成。
支持可选的completion block,在operation的主任务完成后调用。
支持应用使用KVO通知来监控operation的执行状态。
支持operation优先级,从而影响相对的执行顺序
支持取消,允许你中止正在执行的任务
并发 VS 非并发Operations
通常我们通过将operation添加到operation queue中来执行该操作。但是我们也可以手动调用start方法来执行一个operation对象,这样做不保证operation会并发执行。NSOperation类对象的 isConcurrent 方法告诉你这个operation相对于调用start方法的线程,是同步还是异步执行的。isConcurrent 方法默认返回NO,表示operation与调用线程同步执行。
如果你需要实现并发operation,也就是相对调用线程异步执行的操作。你必须添加额外的代码,来异步地启动操作。例如生成一个线程、调用异步系统函数,以确保start方法启动任务,并立即返回。
多数开发者从来都不需要实现并发operation对象,我们只需要将operations添加到operation queue。当你提交非并发operation到operation queue时,queue会创建线程来运行你的操作,因此也能达到异步执行的目的。只有你不希望使用operation queue来执行operation时,才需要定义并发operations。
创建一个 NSInvocationOperation 对象
如果已经现有一个方法,需要并发地执行,就可以直接创建 NSInvocationOperation 对象,而不需要自己继承 NSOperation。
@implementation MyCustomClass
- (NSOperation*)taskWithData:(id)data
{
NSInvocationOperation* theOp = [[[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(myTaskMethod:)
object:data] autorelease];
return theOp;
}
// This is the method that does the actual work of the task.
- (void)myTaskMethod:(id)data
{
// Perform the task.
}
@end
创建一个 NSBlockOperation 对象
NSBlockOperation 对象用于封装一个或多个block对象,一般创建时会添加至少一个block,然后再根据需要添加更多的block。当 NSBlockOperation 对象执行时,会把所有block提交到默认优先级的并发dispatch queue。然后 NSBlockOperation 对象等待所有block完成执行,最后标记自己已完成。因此可以使用block operation来跟踪一组执行中的block,有点类似于thread join等待多个线程的结果。区别在于block operation本身也运行在一个单独的线程,应用的其它线程在等待block operation完成时可以继续工作。
NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
NSLog(@"Beginning operation.\n");
// Do some work.
}];
使用 addExecutionBlock: 可以添加更多block到这个block operation对象。如果需要顺序地执行block,你必须直接提交到所需的dispatch queue。
自定义Operation对象
如果block operation和invocation operation对象不符合应用的需求,你可以直接继承 NSOperation,并添加任何你想要的行为。
NSOperation 类提供通用的子类继承点,而且实现了许多重要的基础设施来处理依赖和KVO通知。继承所需的工作量主要取决于你要实现非并发还是并发的operation。
定义非并发operation要简单许多,只需要执行主任务,并正确地响应取消事件;NSOperation 处理了其它所有事情。对于并发operation,你必须替换某些现有的基础设施代码。
执行主任务
每个operation对象至少需要实现以下方法:
自定义initialization方法:初始化,将operation 对象设置为已知状态
自定义main方法:执行你的任务
你也可以选择性地实现以下方法:
main方法中需要调用的其它自定义方法
Accessor方法:设置和访问operation对象的数据
dealloc方法:清理operation对象分配的所有内存
NSCoding 协议的方法:允许operation对象archive和unarchive
转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
D. ios多线程中gcd的优势及原理,线程池效率问题,何时需要取消线程任务
GCD
1.Apple提供的一套更底层、更高效的并发编程技术,纯C语言、基于Block
2.支持同步或异步任务处理,串行、并行的处理队列,非系统调用的信号量机制,定时任务处理,进程、文件或网络的监听任务等
优点
1.易用:GCD比之thread更简单易用。基于block的特性导致它能极为简单得在不同代
码作用域之间传递上下文
2.效率:GCD实现功能 轻量、优雅,使得它在很多地方比之专门创建消耗资源的线程更
实用且快速
3.性能:GCD自动根据系统负载来增减线程数量,这就减少了上下文切换以及增加了计
算效率
4.安全:无需加锁或其他同步机制
GCD内存管理
1.手动内存管理:dispatch_retain、dispatch_release
·dispatch函数名称中含有‘create’的API在不需要其生成的对象时,必须通过dispatch_release 函数进行释放
2.ARC:iOS6之后GCD兼容ARC,不再需要用dispatch_retain或dispatch_release
E. Web 前端和 iOS 开发,你会选哪个
前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,不像后台想用什么就用什么,iOS只能用Objective-C,前端只能javascript,当然iOS还可以用RubyMotion,前端还能用GWT/CoffieScript,但不是主流,用的人很少,真正用了也会多出很多麻烦。
这两者有个有意思的对比:变量/方法命名的风格正好相反。苹果一直鼓吹用户体验,写代码也不例外,程序命名都是用英文全称并且要多详细有多详细,力求看变量和方法名就能知道是干嘛的,例如application:didFinishLaunchingWithOptions:。而js因为每次都要从网络下载,要力求减少代码体积,所以变量方法名是尽量用缩写,实际上有代码压缩工具,无论变量名写多长最终上线的效果是一样的,但大家也都习惯了用短的命名,例如上述objc的application:didFinishLaunchingWithOptions:方法在js里习惯的命名是:$()。
objc与js都是动态语言,使用起来还蛮像,但objc是编译型,速度快,很多错误也能在编译过程中被发现,js是解释型,性能依赖于解释引擎,即使在强劲的v8引擎下性能也赶不上编译型语言,语言太动态,变量完全没有类型,写起来爽,debug起来稍微费点劲。一直感觉js轻巧灵活放荡不羁充满各种奇技淫巧,objc中规中矩没c++ java那么严肃也没有js那么灵活。
线程
前端开发几乎不需要线程这个概念,浏览器实现上页面HTML和CSS解析渲染可能与js不在同一个线程,但所有js代码只执行在一条线程上,不会并发执行,也就不需要考虑各种并发编程的问题。在新的JS特性中可以创建worker任务,这样的任务是可以另起一条线程并行执行的,但由于并不是所有浏览器都支持,不同线程传递数据各个标准定的还不一样,使用场景也少,似乎没有大规模用起来。对于数据库操作/发送网络请求这样的任务是在不同于js代码执行线程的,不过这些都由浏览器管理,前端无需关心也无法影响这些线程,只需接收事件回调,不需要处理任何并发问题。
终端开发需要大量使用多线程,iOS有一条主线程,UI渲染都在这个线程,其他耗时长的逻辑或者数据库IO/网络请求都需要自己另开线程执行,否则会占用主线程的时间,导致界面无法响应用户交互事件,或者渲染慢导致滚动卡顿。程序逻辑分布在多个线程里跑,需要处理好各种代码并发执行可能带来的数据不一致/时序错乱之类的问题,并发也导致有些bug难以排查,一不留神就掉坑,需要适当用一些队列/锁保证程序的执行顺序。iOS提供了一套多线程管理的方法GCD,已经把线程和队列封装得非常简单易用功能强大,比其他端或后台是好很多了,但还是会花大量功夫在处理多线程问题上。
F. ios 怎么应用响应式编程实现登录
使用ReactiveCocoa实现iOS平台响应式编程
ReactiveCocoa和响应式编程
在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Programming,响应式编程),在维基网络中有这样一个例子介绍:
在命令式编程环境中,a = b + c 表示将表达式的结果赋给a,而之后改变b或c的值不会影响a。但在响应式编程中,a的值会随着b或c的更新而更新。
Excel就是响应式编程的一个例子。单元格可以包含字面值或类似”=B1+C1″的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化 。
而ReactiveCocoa简称RAC,就是基于响应式编程思想的Objective-C实践,它是Github的一个开源项目,你可以在这里找到它。
关于FRP和ReactiveCocoa可以去看leezhong的这篇blog,图文并茂,讲的很好。
ReactiveCocoa框架概览
先来看一下leezhong再博文中提到的比喻,让你对有个ReactiveCocoa很好的理解:
可以把信号想象成水龙头,只不过里面不是水,而是玻璃球(value),直径跟水管的内径一样,这样就能保证玻璃球是依次排列,不会出现并排的情况(数据都是线性处理的,不会出现并发情况)。水龙头的开关默认是关的,除非有了接收方(subscriber),才会打开。这样只要有新的玻璃球进来,就会自动传送给接收方。可以在水龙头上加一个过滤嘴(filter),不符合的不让通过,也可以加一个改动装置,把球改变成符合自己的需求(map)。也可以把多
G. 麻烦给完整编程
print('\n'.join(input('请输入多种水果名称:').strip().split()))
H. 编程时选用的程序设计语言,对软件的开发与维护的影响
【CSDN 编者按】“如果我们把人类文明想象成汽车的话,那么软件开发行业就相当于汽车的引擎,编程语言就像引擎的燃料。”作为一名开发者,需跟随技术潮流的发展来学习新技术。2020年,你有计划新学一门编程语言吗?
本文作者从一名架构师的角度,详细分析了7种现代编程语言的优点与功能,你对哪门语言最感兴趣呢?
作者 | Md Kamaruzzaman,软件架构师
译者 | 弯月,责编 | 伍杏玲
封图| CSDN 下载于视觉中国
出品 | CSDN(ID:CSDNnews)
以下为译文:
如果我们把人类文明想象成汽车的话,那么软件开发行业就相当于汽车的引擎,而编程语言就像引擎的燃料。作为一名开发者,今年你应该学习哪种编程语言呢?
学习一种新的编程语言无疑是时间、精力和智力上的巨大投资, 但是学习一种新的编程语言可以提升你的软件开发技术力,促进你的职业发展。
在这里,我将献上一份现代编程语言的列表,这些语言不仅有助于提高你的生产力,而且还可以促进你的职业发展,并让你成长为更优秀的开发人员。这份列表还涵盖了非常广泛的领域:系统编程、应用程序开发、Web开发、科学计算等。
什么是现代编程语言?
“现代编程语言”这个说法本身就很含糊。许多人认为Python和JavaScript等语言是现代编程语言,还认为Java是一种古老的编程语言。实际上,这几种语言大约在同一时间出现:1995年。
大多数主流编程语言是上个世纪开发的:七十年代(如C)、八十年代(如C ++)、九十年代(如Java、Python、JavaScript)。这些语言在设计上并没有考虑现代软件开发生态系统:多核CPU、GPU、快速的互联网、移动设备、容器和云等。尽管许多语言中的许多功能都已进行一些改进,如并发等,而且在不断调整自己以适应时代,但它们依然保留了向后兼容性,无法抛弃那些过时的旧功能。
在这方面,Python就做得很好(某种意义上也未必是好事),Python 2和Python 3两者之间有明确的分界线。很多语言常常会为解决同一个问题提供十余种的方法,同时又没有顾及到开发人员的感受。根据StackOverflow的开发人员调查,大多数旧时的主流编程语言在“最可怕的语言”排名都名列前茅:
如果非要在新旧编程语言之间划个界限的话,那么应该是2007年6月29日,也就是第一台iPhone发行的时候。在这之后,编程语言界发生了很大变化。因此,在本文的列表中,我只考虑2007年以后的编程语言。
为什么要学习新语言?
首先,现代编程语言充分利用现代计算机硬件(多核CPU、GPU、TPU)、移动设备、大量数据、高速互联网、容器和云的优势。大多数现代编程语言会关注开发人员的体验,比如:
简洁明了的代码(减少样板代码)
内置的并发支持
空指针安全
类型推断
简洁的功能集
降低学习难度
融合所有编程范例的最佳功能
本文列表的许多编程语言都带有革命性地变化,并将永久地改变软件行业。一些已成为主流编程语言,还有一些则有望取得突破。因此选择这些语言作为第二种编程语言是明智的做法。
Rust
一直以来,系统编程语言环境主要由靠近硬件的语言(如C、C ++等)主导。尽管它们可以完全控制程序和硬件,但是它们缺乏内存安全性。即使它们支持并发,使用C/C ++编写并发程序也很困难,因为没有并发安全性。还有一些流行的编程语言是解释性语言,例如Java、Python、Haskell。这些语言具备安全性,但需要庞大的运行时或虚拟机。由于它们的运行时间长,因此Java等语言不适合于系统编程。
许多人曾尝试将C/C ++的功能与Java、Haskell的安全性相结合。然而,Rust才是第一个成功实现了这一点的编程语言。
Graydon Hoare在业余项目中开发出了Rust,他的灵感来自研究编程语言Cyclone。Rust是开源的,由Mozilla与许多其他公司和社区一起领导这门语言的开发。Rust于2015年首次发布,并很快引起了社区的关注。
主要特征:
通过所有权和借用概念提供内存安全和并发安全。
内存安全和并发安全在编译时确保,即如果程序代码可以编译,那么内存既安全又没有数据竞争。这是Rust最吸引人的功能。
它还提供了Haskell中元编程的表现力。凭借不可变的数据结构和功能编程功能,Rust提供了功能并发和数据并发。
Rust的速度非常快,纯Rust的性能甚至优于纯C。
在没有运行时的情况下,Rust可以完全控制现代硬件(TPU、GPU、多核CPU)。
Rust具有LLVM支持。因此,Rust提供一流的与WebAssembly的互操作性,而且Web代码也非常快。
流行度:
自2015年首次亮相以来,Rust已被开发人员广泛接受,并在StackOverflow开发人员调查中连续四年(2016、2017、2018、2019)被评选为最受欢迎的语言:
根据GitHub Octoverse的调查,Rust是运行速度第二快的语言,仅次于Dart:
此外,根据编程语言流行度排名网站PyPl的数据,Rust排名第18位,并呈上升趋势:
对比Rust提供的功能集,我们就会明白为什么微软、亚马逊、Google等科技巨头相继宣布投资Rust作为一种长期的系统编程语言。
根据Google统计的趋势,在过去的5年中,Rust的热度每年都在增加。
主要用途:
系统编程
Serverless 计算
商业应用
主要竞争对手:
C
C++
Go
Swift
Go
在本世纪初,Google面临两个扩展问题:开发扩展和应用程序扩展。开发扩展问题指的是他们不能仅通过投入开发人员的方式来添加更多功能。应用程序扩展问题则指他们无法开发出一款能够扩展到Google级别的计算机集群的应用程序。
所以在2007年左右,Google创建了一种新的编程语言,用于解决这两个扩展问题。两位才华横溢的Google软件工程师Rob Pike(UTF-8)和Ken Thompson(UNIX OS)创建了一种新语言。
2012年,Google正式发布了第一版的Go编程语言。Go是一种系统编程语言,但与Rust不同,它还具有Runtime和垃圾收集器(几兆字节)。但是与Java或Python不同,这个Runtime包含了生成的代码。最后,Go生成了一个本地的二进制代码,可以在没有附加依赖项或运行时的情况下在计算机中运行。
主要特征:
Go具有一流的并发支持。Go不通过线程和锁提供“共享内存”并发性,因为编程难度太大。相反,它提供了基于CSP的消息传递并发性(基于Tony Hoare的论文)。Go使用“ Goroutine”(轻量级绿色线程)和“ Channel”进行消息传递。
Go最大的杀手级功能是:简单,它是最简单的系统编程语言。新手软件开发人员只需几天就可以编写高效的代码,就像Python一样。有些大规模的云原生项目(如Kubernetes、Docker)都是用Go编写的。
Go还内置了垃圾收集器,这意味着开发人员无需担心C/C++中的内存管理问题。
Google投入了大量资金打造Go。因此Go拥有大量的工具支持。新手Go开发人员拥有大量的工具生态系统。
一般,开发人员80%的时间都花在了维护现有代码上,用于编写新代码的时间只占20%。由于其简单性,Go在语言维护方面表现出色。如今,Go在业务应用程序中大量使用。
流行度:
Go一问世就受到了软件开发社区热烈的欢迎。2009年-2018年,Go一直在TIOBE编程语言排行榜上徘徊。Go的成功为Rust等新一代编程语言铺平了道路。
如今,Go已是主流编程语言。最近,Go团队宣布了有关“Go 2”的消息,这门编程语言的发展会更加稳固。
几乎在所有的流行编程语言排行榜中,Go的排名都很高,已超过许多现有的语言。自2019年12月以来,在TIOBE指数排名中,Go名列第15位:
根据StackOverFlow的调查,十大最受喜爱的编程语言中,Go也位列其中:
此外,根据GitHub的数据,Go也是十大发展最迅速的语言之一:
Google趋势显示,在过去的5年中,Go的热度每年都在增加。
主要用途:
系统编程
Serverless 计算
商业应用
云原生开发
主要竞争对手:
C
C++
Rust
Python
Java
Kotlin
Java 是企业软件开发领域无可争议的王者。近年来,Java受到了一些负面评论:过于冗长,大量样板代码,容易出现意外的复杂性。但是,关于Java虚拟机(JVM)的争论却很少。JVM是软件工程的杰作,经过了时间的考验,提供了硬核的runtime。
多年来,Scala等JVM语言一直在努力克服Java的缺点,想成为更好的Java,但他们都失败了。最终,这场提升Java的探索以Kotlin的诞生结束。Jet Brains(流行的IDE IntelliJ背后的公司)开发了Kotlin,它可以在JVM上运行,克服了Java的很多缺点,提供许多现代功能。
与Scala不同的是,Kotlin比Java更简单,还可在JVM中提供与Go或Python开发人员同等的生产力。
Google宣布Kotlin是一流的Android应用开发语言,因此Kotlin在社区中的接受度得到了大幅提高。自2017年以来,同样受欢迎的Java Enterprise框架Spring也开始支持Kotlin。我曾尝试结合Kotlin与Reactive Spring使用,体验非常棒。
主要特征:
Kotlin的主要卖点在于其语言设计。我总是将Kotlin视为JVM上的Go/Python,因为它简洁明了的代码。因此,Kotlin的生产力很高。
与许多其他现代语言一样,Kotlin提供了Null指针、安全性、类型推断等功能。
由于Kotlin也运行在JVM中,因此现有Java库庞大的生态系统都可供使用。
Kotlin是一流的Android应用开发语言,并且已经超过Java,成为开发Android应用的首选。
Kotlin得到了JetBrains和Open Source的支持,因此具有出色的工具支持。
Kotlin有两个有趣的项目:Kotlin Native(将Kotlin编译为原生代码)和kotlin.js(Kotlin到JavaScript)。如果成功,则可以在JVM外部使用Kotlin。
Kotlin还提供了一种简单的方式来编写DSL(域特定语言)。
流行度:
自2015年首次发布以来,Kotlin的知名度不断飙升。根据Stack Overflow,Kotlin是2019年第四大最受欢迎的编程语言:
Kotlin还是增长最快的编程语言之一,排名第四:
在流行编程语言排名网站PyPl的排名中,Kotlin名列第十二名,并具有较高的上升趋势:
自从Google宣布Kotlin是一流的Android应用开发语言以来,Kotlin的流行趋势出现了大幅上涨,如下所示:
主要用途:
企业应用程序
主要竞争对手:
TypeScript
JavaScript是一门优秀的编程语言,在2015年之前,JavaScript有很多缺点。着名的软件工程师Douglas Crockford写了一本书名为《JavaScript: The Good Parts》,暗示了JavaScript有很糟的部分。无模块化,还有“回调地狱”,因此开发人员都不喜欢维护特别大的JavaScript项目。
Google甚至还开发了一个平台,可将Java代码反编译为JavaScript代码(GWT)。许多公司和个人都曾尝试开发更好的JavaScript,例如CoffeeScript、Flow、ClojureScript。最终,微软的TypeScript取得了成功。
微软的一队工程师在着名的Anders Hejlsberg的带领下,创建了JavaScript的静态类型、模块化超集——TypeScript。
TypeScript可以编译为JavaScript。于2014年首次发布后,TypeScript很快引起了社区的关注。Google当时还计划开发JavaScript的静态类型超集。Google对TypeScript青睐有加,以至于他们没有开发新的语言,而是选择与微软合作改进TypeScript。
Google选择TypeScript作为其SPA框架Angular 2+的主要编程语言。此外,流行的SPA框架React也提供对TypeScript的支持。另一个流行的JavaScript框架Vue.js也宣布将使用TypeScript开发新的Vue.js 3:
另外,node.js的创建者Ryan Dahl已决定使用TypeScript来开发安全的Node.js替代品Deno。
主要特征:
流行度:
开发人员喜欢TypeScript的优雅语言设计。在StackOverFlow最受欢迎的语言类别的调查中,TypeScript与Python并列第二名:
根据GitHub的排名,TypeScript是增长最快的编程语言之一,排名第五:
从GitHub的贡献度来看,TypeScript排名第七,打进了前十:
Google的趋势表明,在过去的几年中,TypeScript的热度越来越高:
主要用途:
主要竞争对手:
Swift
当初乔布斯拒绝在iOS中支持Java(和JVM),他认为Java不再是主流编程语言。如今我们发现乔布斯当初的估计是错的,虽然iOS仍然不支持Java。苹果选择了Objective-C作为iOS中的首选编程语言。Objective-C是一门很难掌握的语言,它不支持现代编程语言所要求的高生产力。
后来,苹果的Chris Lattner和其他人开发了一种多范例、通用的、编译编程语言——Swift,来替代Objective-C。Swift的第一个稳定版本于2014年发布。Swift还支持LLVM编译器工具链(也由Chris Lattner开发)。Swift与Objective-C代码库具有出色的互操作性,并且已确立为iOS应用开发中的主要编程语言。
主要特征:
流行度:
开发人员对Swift的喜爱不亚于许多其他现代编程语言。根据StackOverflow的调查,Swift在最受欢迎的编程语言中排名第六:
2019年,在TIOBE的编程语言排名中,Swift的排名上升到了第10名。鉴于这种编程语言只有5年的历史,可以说是成绩斐然:
Google的趋势表明,在过去的几年中,Swift的热度出现了激增:
主要用途:
主要竞争对手:
Dart
Dart是Google出品的第二大编程语言。Google是Web和Android领域的巨头,因此Google在Web和应用领域开发自己的编程语言也不足为奇。在丹麦软件工程师Lars Bak(领导Chrome的 JavaScript V8引擎开发)的带领下,Google于2013年发布了Dart。
Dart是一种通用编程语言,支持“强类型”和“面向对象”编程。Dart也可以转编译为JavaScript,凡是JavaScript可以运行的任何地方(例如Web、移动、服务器)几乎都可以运行 Dart。
主要特征:
流行度:
根据GitHub Octoverse数据显示,Dart是2019年增长最快的编程语言,去年它的流行度增长了五倍:
根据TIOBE指数显示,Dart排名第23,仅用了4年时间就超过了很多其他的现代编程语言:
根据StackOverflow的调查,Dart在最受欢迎的编程语言中排名第12:
受Flutter的影响,Google的趋势表明,在过去的两年中,Dart的热度急剧上升:
主要用途:
主要竞争对手:
Julia
本文提及的大多数编程语言都是由大型公司开发的,但Julia是个例外。科技计算领域通常都会使用动态语言,例如Python、Matlab。虽然这些语言提供易于使用的语法,但不适用于大规模的科技计算。他们需要使用C/C ++库执行CPU密集型任务,因此这就产生了着名的“两种语言”的问题,因为他们需要粘合代码来绑定两种语言。由于编写的代码需要在两种语言之间来回切换,因此总是会损失部分性能。
为了解决这个问题,麻省理工学院的一队研究人员计划从头开始创建一种新的语言,这种语言既可以利用现代硬件的优势,而且还结合其他语言的优势。于是,Julia诞生了。
Julia是一种动态的高级编程语言,提供一流的并发、并行和分布式计算支持。Julia的第一个稳定版本于2018年发布,并很快受到社区和行业的关注。Julia可用于科学计算、人工智能和许多其他领域,而且还可以解决“两种语言”的问题。
主要特征:
流行度:
Julia在许多领域主要与Python竞争。由于Python是最流行的编程语言之一,因此Julia想晋升主流还需要几年的时间。
虽然Julia非常新(只有一岁),但仍在TIOBE指数中排到第43名:
Google趋势显示,在过去的一年中,Julia的热度在稳步增长:
但是考虑到Julia的功能集,以及NSF、DARPA、NASA、因特尔等公司的推动,相信Julia取得突破的进展只是时间的问题。
主要用途:
主要竞争对手:
原文链接:https://towardsdatascience.com/top-7-modern-programming-language-to-learn-now-156863bd1eec
本文为 CSDN 翻译,转载请注明来源出处。
【End】
Python
Matlab
科学计算
高性能计算
数据科学
可视化
与Rust一样,Julia的主要特征在于语言的设计。这种语言在不牺牲性能的情况下,将高性能和科学计算中现有编程语言的一些功能结合在一起。就目前的情况来看,Julia出色地完成了这项任务。
Julia是一种动态编程语言,支持类型系统但类型不是必须的。因此,Julia这种编程语言很容易学习,生产力很高。
Julia的核心是多调度编程范例。
Julia内部支持并发、并行和分布式计算。
Julia为I/O密集型任务提供异步I/O。
Julia的运行速度非常快,可用于需要数百万个线程的科学计算。
JavaScript
TypeScript
应用开发
UI开发
与Go一样,Dart也非常注重开发人员的工作效率。由于Dart简洁的语法,以及高效的生产力,受到开发人员的喜爱。
Dart还提供“强类型”和“面向对象”编程。
Dart是少数同时支持JIT编译(运行时编译)和AOT编译(创建时编译)的编程语言之一。因此,Dart可以针对JavaScript运行时(V8引擎),并且Dart可以编译为快速的原生代码(AOT编译)。
跨平台原生应用程序开发平台Flutter选择了Dart作为开发iOS和Android应用的编程语言。从那以后,Dart的流行度越来越高。
与Goog的Go编程语言一样,Dart也具有出色的工具支持和庞大的Flutter生态系统。Flutter的日益普及也会推动Dart的采用率升高。
Objective-C
Rust
Go
iOS应用开发
系统编程
客户端开发(通过WebAssembly)
Swift的杀手级功能之一是其语言设计。语言本身很简单,语法简洁,比Objective-C更高效。
Swift还提供了现代程序语言的功能:null安全。此外,它还提供了语法糖来避免“厄运金字塔”。
作为一种编译语言,Swift和C++一样快。
Swift支持LLVM编译器工具链。因此,我们可以在服务器端编程,甚至浏览器编程(使用WebAssembly)中使用Swift。
Swift提供了自动引用计数(ARC)支持,可抑制内存管理的不善。
JavaScript
Dart
Web UI开发
服务器端开发
与Go或Kotlin同样,TypeScript的主要特征也是语言设计。TypeScript凭借其简洁明快的代码,成为了目前最优雅的编程语言之一。就开发人员的生产力而言,它与JVM或Go/Python上的Kotlin并驾齐驱。TypeScript是生产力最高的JavaScript超集。
TypeScript是JavaScript的强类型超集,特别适合大型项目,而且可以称为“可扩展的JavaScript”。
单页应用程序框架的“三巨头”(Angular、React、Vue.js)为TypeScript提供了出色的支持。在Angular中,TypeScript是首选的编程语言。在React和Vue.js中,TypeScript越来越受欢迎。
最大的两家技术巨头:微软和Google正在合作开发由活跃的开源社区支持的TypeScript。因此,TypeScript拥有最好的工具支持。
由于TypeScript是JavaScript的超集,因此凡是可以运行JavaScript的任何地方都可以运行TypeScript,包括浏览器、服务器、移动设备、物联网设备和云。
Java
Scala
Python
Go
I. 请问现在从零开始学习iOS开发,学习Objective-C语言还是学习Swift语言
没基础从C学起,C不需要深入,搞懂指针(指向函数/结构体/数组的指针),搞懂结构体就基本OK了。
有基础直接进入OC,C++可用无视(以后做游戏用cocos2dx框架才考虑吧)。别听一楼这逗比的回答,他根本什么都不懂.....可能根本就不会编程。就来这里瞎说的。
虽然上年推出了swift,但是你知道现在的SDK基本上都是用OC来写的吗?80%的API接口都是用OC来写的,现在的苹果本质上只是帮你封装好了,底层帮你装换成OC。(需要给苹果一点时间来完善SDK,或许1、2年吧)还有更底层的,例如GCD(并发编程方面),CG框架(绘图用的)。等等等等。。。。。都是赤裸裸的C语言。没有OOP的概念。你说你需要有C和OC的基础吗?
还有现在的公司,特别是大公司,基本上的项目都是OC写的,你不会OC?你怎么读懂代码?怎么重构代码?不要说OC,很多公司的老项目,连SB和NIB都没有(一是当时没有SB,而是当时用SB不方便源代码管理,这个等到你有开发经验了才会理解...),都是100%纯手写代码的。除非开启一些新项目才会有IB。不要说看不懂OC,你连面试关都过关了,因为单单OC这个知识点就考死你了。
所以说基础一定要扎实。还是一步一步来吧,最后告诉你,你有基础的话,swift根本不用学,我当时用了1天看文档,就彻底搞懂swift了....
J. ios数据加载完会调用哪个方法
1.下面来看下如何使用gcd编程的异步
Objective-c代码
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 处理耗时操作的代码块...
//通知主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回调或者说是通知主线程刷新,
});
});
复制代码
dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。
dispatch_get_global_queue(0, 0),指用了全局队列。
一般来说系统本身会有3个队列。
global_queue,current_queue,以及main_queue.
获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低
Objective-c代码
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
复制代码
处理完事物后,需要将结果返回给或者是刷新UI主线程,同样,和上面一样,抓取主线程,程序块操作。
//天啊,手贱不小心点到了home间,会退后发现没保存~~~写的并发一块内容都没了!!!
二:GCD之并发概念
其实对于编程中,我们一直提及到的几个概念,同步,异步,并发,锁等。
有时觉得一下子还真说不清。
下面我们以上面提到的图片加载来看下这3个概念我的理解
1同步:
Objective-c代码
for (int i = 0 ; i < 10; i++) {
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
[myImgV[i] setImage:img];
}
复制代码
假设我要加载10个图片,我现在拥有这些图片的资源地址,保存在一个数组中。
我们先以获取第一张图片来举例:
同步执行的概念就是,我获取完第一张图片的,
执行了for循环第一句返回了img后,我才能执行第二句,UI界面的刷新。
如果第一句返回的时间需要10秒,那我程序的响应就仿佛一直卡在这里一样,我无法进行其他操作。必须等它返回!!
因此,同步的一个很好理解的感念就是,一步走到黑。
2.异步
for (int i = 0 ; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 处理耗时操作的代码块...
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
//通知主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回调或者说是通知主线程刷新,
[myImgV[i] setImage:img];
});
});
复制代码
看了这代码,我们会说,异步操作那个假设还是要10秒啊,总体看来,执行一张图片的时间加载还是要在10秒左右啊,
貌似异步没什么鸟用么。但是,别忽略了其中一点,也黑丝核心的一点,此时我们图片获取操作放在里一个线程队列里,
此刻,虽然我们看着图片的加载还是需要10秒才会出来,但是,在这10秒期间,我们的UI主线程是可以操作的,比如界面上有个按钮,你是可以按的
而不是如上面的同步,在10面期间,我是只能干等着,什么都做不了。
异步的核心概念就是一个新线程,一个消息回调通知。
3.并行
我们还是以上代码为例。前面我强调了,我们只看一张图片的加载,现在,回到我们第一眼看到代码的思维上去,
一个for循环。其实上面代码过后,我是创建了10个异步线程。
好吧,到此,我们应该明白这三个概念了。
同步,其实我前面的例子举得有些局限,就是这个例子本身就说明不需要同步执行,然后给大家大感觉是
同步是编程中一个忌讳点一样,其实不然,很多时候。我们真是需要同步来做一些限制(比如线程中提出的同步锁?听着就感觉有用么
虽然可能并不如我们想的那样的运用同步,但是至少说明这个概念同样是有用的)
我还是以刚才那个加载图片为例子,来个简单的说明如何运用同步的好处。
当然,我只是模拟一个同步的情况。
假设我们现在图片的加载是这样的,图片本身为在加载前是一个默认的图片,上面写着,点击我加载,点击后会调用网络加载方法,然后图片显示加载中,
然后我们双击图片时(当然,理论上是在加载完后)读取图片网络图片放大,好吧,到这里应该能想到要表达的情况了。
整个流程应该是点击图片->加载->双击查看。那如果成了点击->加载中(以返回了图片的作者和信息)-》双击图片(通过前面请求返回的大图链接显示大图)-》
完全加载返回(返回了大图链接)。此时我们看不到图像的大图了。因为我们操作在返回前了,也就是说,
很多时候,我们下一个动作的操作必须需要用到前面一个操作的数据时,我们会给他做认为的同步编程,比如加个按钮锁。
这是我们又会疑惑道,下一个执行需要用到前一个执行的,那第一个例子中的for循环的第二句不是要用到么,这么说
他们必须要同步啊,如果你这么想了,好巧,我们想到一块去了~
但是,注意,前面我们到的异步是为了解决我点击其他按钮的操作,而不是说更新UI操作。下载和更新UI操作在我们看来必须是同步的
这是对的,但是那种做导致了系统本身一些监听事件监听到点击处理在那个请求之后了,这边的加载图片其实要看成一次事件执行,
因为对于事件的这一抽象单元,其实是一种可人为定义的宽广度。
也就是说,一次数据获取和图像填充,其实算是一个图像获取加载事件,事件可以说包含两个单元,加载和填充。
而整个这个事件对于我们点击其他按钮并无关系,那么也就说明了无需同步。
有道理啊,但是若果我们要点击这个图片呢,也就是回到刚才那个可以双击的假设。
此处也许我么又忽略了一点为什么加载中我们能点击双击呢,也就这样的假设是获取图片已经做了异步,但是我们下一步操作又是需要同步的
因此做了人为的同步锁定。
好了,说的太多了,当时至少我们明白两点
异步可能是为了反正耗时操作造成的主线程堵塞,
同步是为了解决一些不必要错误和麻烦。也许到这里,我们脑中会联想到的所谓的线程安全性。
其实同步以及同步锁,却是应该是考虑到这样的不必要和不安全因素。
最后在简单阐述下异步和并发关系。
其实看了上面说的,异步只是提供了一种多线程处理的概念,
并发是更像是异步的一种大规模实现。
就好比说,异步提出了可以用小弟去收保护费,收完了告诉并交给自己,而我在期间做其他要做的事。
并发突然想到,异步这个很有道理啊,那我有4个地方要收,一个小弟去收,虽然我还是可以闲着做其他的事,
但是小弟跑四个地方,我拿到钱所需要的时间还是和我自己去收一样的,只不过我不用那么费劲了,还能做其他事了。
因此,并发觉得应该派四个小弟去,因为每个场地的保护费各不相干的。(刚看了个纽约黑帮~)。
因此说,异步解决了线程堵塞,而并发则是在异步的基础上,提高了符合特性事件的处理时间效率。
当然,如果10个图片本身相互间是没什么联系,但是,最后一个事件需要处理计算这10个图片的总容量值。
那么可以用 dispatch_group_async。
具体就看文档吧。
总体来说,看了iosGCD这块,一是让我熟悉了block编程特性,还有是熟悉如何使用ios提供的GCD特性
来完成多线程编程。