扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这篇文章主要介绍了实际应用 MVVM 的过程中的一些问题和解决方案
成都创新互联致力于互联网品牌建设与网络营销,包括成都网站设计、成都网站建设、SEO优化、网络推广、整站优化营销策划推广、电子商务、移动互联网营销等。成都创新互联为不同类型的客户提供良好的互联网应用定制及解决方案,成都创新互联核心团队10多年专注互联网开发,积累了丰富的网站经验,为广大企业客户提供一站式企业网站建设服务,在网站建设行业内树立了良好口碑。
MVVM(Model View ViewModel)是一种 MVC(Model View Controller)的一种变型,来解决 MVC 中庞大复杂的 Controller 难以维护的问题。大致上讲 MVVM 有几个要求:
MVVM 和 MVC 有很多类似的特点,主要的不同有:
另外一点,MVVM 默认 View 和 View Controller 有一个一对一的关系,一般我们把这两个看做一个整体,会以 .swift 文件 和 Storyboard 的形式出现。
View Model 的工作是处理所有的展示数据的逻辑。如果一个 model 中有一个 NSDate 对象, NSDateFormatter 就会在 View Model 中用来设置日期的展示形式。
View Model 不能接触任何用户界面的部分,View Model 文件中不应该 import UIKit ,View Controller 会观察 View Model 去了解什么时候显示新的数据(通过 KVO 或者 FRP(Functional Reactive Programming))
MVVM 和 MVC 有一个共同的弱点:没有清楚的定义应该把网络请求部分放在哪里。在实际操作过程中,我会把网络请求放在 View Model 文件里面,但之后我打算把网络请求放在自己独立的一个类中,View Model 文件会拥有这个对象。
下面我们主要谈一谈实际应用 MVVM 过程中一些挑战:
例如你想构造这样一个常用的界面,有一个 segment control 在屏幕顶部,屏幕的其他部分是一个 collection view,选择不同的 segment,就会展示不同样式的 collection view,元素的排列顺序。我们定义了一个 enum 来枚举所有的排列样式:
那么这个 enum 在 MVVM 模式中应该放在哪里呢?因为这个 enum 决定了数据排列的顺序,每个 cell 中的文字和按钮的 title,这些都属于展示的逻辑,所以这个 enum 看起来应该放在 view model 中。
然而,这些 layout 并不改变要展示的数据,只是决定了要呈现的数据的排列方式和排列顺序,从这个角度上来说 enum 又应该放在 view controller 中。
我的解决方法是把 enum 放在 view model 中,然后在 view model 中加一个对外的 Observable 或者 Signal 来表示使用了哪个 layout,基于用户选择的 segment,view model 更新这个值,然后在 view controller 中根据相应的 layout 改变 collection view 的样式,view controller 也可以根据这个值来决定用哪个 cell reuse identifier
iOS 开发者在用 MVVM 和 FRP 写应用的时候最常见的问题可能就是 ViewModel 怎么把数据展现给 ViewController。当 Model 层的数据发生变化更新的时候,ViewController 需要得到通知然后做出相应的 UI 更新,我们一般会用到两种机制:
第一个选项很吸引人,因为可以在 View Controller 中决定怎么选择观察那些 property。然而,我不推荐在 Swift 中使用第一个选项,因为 Swift 在 KVO 中没有类型检查,你需要对 AnyObject 强制转换类型很多次。
第二个选项是比较 Swift 的方式,基于 Swift 的 generics 特性,signals,sequences,observables 可以支持编译过程中的类型检查。
但有时候在 view model 增加这些 Signals 或者 Observables 有些困难。Swift 的初始化方法对于什么时候对 property 赋值有非常明确的规定。Signals 或者 Observables 需要使用 view model 内部的状态,所以它们必须在 super.init() 之后才能创建,但是另一方面,我们在调用 super.init() 之前保证所有 property 已经被赋值了,包括那些 Signal/Observable property。
这是个先有鸡还是先有蛋的问题。
我采用比较简单的解决方法:定义成 var 的隐式可选类型,这样就可以在 super.init() 之后才给 property 赋值。这不是一个完美的解决办法。我们可以用 lazy var property 的闭包赋值来代替上面的方法。在 Swift 不断完善和更新的过程中,大家也可以探索其他更好的办法。
举一个很常用的例子,用户点击 collection view 中的一个 cell,跳转到详情页面。用户点击的操作应该在 view controller 中处理,具体内容是展现一个新的详情页面。但是 view controller 不能直接接触 models,我们要如何用 MVVM 模式实现这样的用户交互呢?
我的解决方案是利用 Swift 的闭包。首先在 view model 中定义一个闭包:
然后在 view model 中添加一个 property:
接着我需要调用闭包,在 view model 中定义一个view controller 可以调用的函数,这个函数的参数是可以决定使用什么数据,一般情况下常用 index path:
现在当用户选中一个 cell,会调用 view model 中的这个函数,并且传入 index path 参数,view model 决定使用哪个数据,并调用在 view controller 中定义的闭包,例如:
最后一个问题是怎么创建这个 view model。我们需要传递一个闭包给view model 的初始化函数,然后用 lazy loading 来调用 view model 的初始化函数。
收起键盘的方法:
这个方法是我不久前碰到的,觉得有用,就记下来了。
该点源自:《iOS开发进阶》 —— 唐巧
总结
我总结出来了四种收起键盘的方法,使用场合如下:当你能获取到 UITextField 对象时,最好使用 [obj resignFirstResponder] 方法; 如果有很多个 UITextField 对象,你也可以获取到 viewController 的 view 时,你可以使用 [[[UIApplication sharedApplication] keyWindow] endEditing:YES] 方法; 如果当前 ViewController比较难获取,那么可以使用第3种或第4种方法。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:Franz Fang
链接:
来源:知乎
不管是斯坦福大学的CS193p公开课、苹果官方文档、绝大多数市场上庞杂的教学书籍都不是很适合入门同学看,想入门的话应该选用学习成本最低的方法,从最最基本开始讲起,并不是一味的讲解语法与知识,而是一边实践一边学习知识才是最好的学习方法。
并且我想告诉题主,你问的是iOS 开发怎么入门,但是你补充说明里说道的设计模式、内存管理等内容暂时不用你关心,等你真正iOS入门了以后在研究吧。也许我可以这么定义你的问题:
一个略懂编程的人并且完全没有接触过IOS开发的人想要学习IOS开发应如何学习?
--------------- 2015.5.15 更新 --------------
增加了怎么在Github上找优质OC项目
动画效果推荐的教程
部分段落重新组织了语言
(一)objective-c语言开发iOS应用
为什么不让初学者看斯坦福教程:我以为,斯坦福大学IOS公开课不适合入门的同学看,里面第一课讲解的就是MVC模式。对于一个刚入门想要学习的IOS的同学可能就完全懵了,心里想:“我特么第一课都听不懂我后面还学个P啊”。如果以前没接触过面向对象的语言学习的热情肯定大打折扣。
为什么不让初学者看苹果官方文档:我还以为,苹果官方文档的内容虽然权威但example对初学者一点都不友好,而且个人认为中文译文翻译不是令初学者很容易理解。初学阶段,教程的易理解程度我认为是非常重要的一点。(实在要看请看英文原版。)
我不否认以上两者是极好的学习材料,如果你入门了iOS开发并且有一定的英文功底,我是非常推荐你去看的,尤其官方文档,应该经常翻阅。但是我认为保持学习的热情是最重要的。本着这个理念,我推荐的学习方法难度非常低,希望你们能满意。
第一阶段: RayWenderlich网站中的 The iOS Apprentice教程 (难度指数:※)
img src="" data-rawwidth="646" data-rawheight="560" class="origin_image zh-lightbox-thumb" width="646" data-original=""以上有几个答案提到了这个网站,但看什么教程没有细说,我在这里简单说说。The iOS Apprentice的教程针对完全没有编程经验的人设计。这个教程是外国人写的并且有免费试读版,感兴趣的人要看看。里面说的东西都非常非常基本,里面一个共讲解了4个不同类型app,强烈建议一步一步按照上面所写的步骤敲一遍代码。其中你会遇到很多复杂的语句和长的可怕的函数,你不用感到恐慌,照着敲,知道它干嘛用完全OK了,随着你编程时间以及经验的增加,你都会懂得。以上有几个答案提到了这个网站,但看什么教程没有细说,我在这里简单说说。The iOS Apprentice的教程针对完全没有编程经验的人设计。这个教程是外国人写的并且有免费试读版,感兴趣的人要看看。里面说的东西都非常非常基本,里面一个共讲解了4个不同类型app,强烈建议一步一步按照上面所写的步骤敲一遍代码。其中你会遇到很多复杂的语句和长的可怕的函数,你不用感到恐慌,照着敲,知道它干嘛用完全OK了,随着你编程时间以及经验的增加,你都会懂得。
附链接:
注:这个教程是英文原版,并且收费,只免费提供一个app的教程。如果看完了这个免费的教程觉得还挺想继续学的请参考 @王寒 老师的翻译教程(只有前3个app教程,第4个教程刚出,国内应该还没有人翻译,如果想看只能付费)。PS:(现在开发iOS应用基本都是用Objective-C,至于刚出来的Swift现阶段暂时不推荐学习,如果想了解王寒老师也做了swift版本的The iOS Apprentice教程翻译,自己去找)
附上王寒老师教程下载地址:
第二阶段:培训班的网络课程及入门书籍
经过第一个阶段你应该已经大致掌握IOS开发流程,能编写一个非常简单的应用了。这时候相信你的热情应该会很高涨,但接下来的学习可能会很枯燥,做好准备。网络课程的话推荐李明杰的课程,不推荐其他的。(他目前在广州创业建立自己的培训品牌,没有自制力看网络课程的请去找他。杰哥开源了一些非常优秀的框架如:MJExtension )
建议首先要恶补基础知识。经过第一个阶段你可能觉得你懂不少了,但是只是表面,尤其是没学过编程的应该好好学习一下视频前面的课程,主要看看语法。等你看恶心了看烦了就去看视频里UI部分,这里相对于来说比较轻松,一定要把视频里写的语句打一遍,相信这样你理解会更深刻。里面说的不清楚的地方上网可以百度,可以查书(如果你有书的话)。
Q:视频教程是用来做什么的?
A:光有实践没有知识是写不好程序的,第一阶段基本都是实践,第二部分则是用来查缺补漏。 之所以推荐网络课程是因为讲解的比较系统,各种入门知识都会涉及。因为iOS所涉及内容庞 大单看几本书还是涉及不全的。
Q:上不上培训班?
A:个人意见是不推荐去,自学足够了。现在学习iOS的环境比前几年好太多了,光凭借网上的资料是 完全可以的学得很好的,如果你连这点学习能力还没有我也不相信你将来能成为一个很优秀的工程师。而且你会发现在社会上一些互联网公司是拒绝接收培训班出来的人。
推荐入门书籍:
tips:以下所有书籍有英文版看英文版,有最新版看最新版
1、《Objective-C 程序设计》(难度指数:※※)
2、《iOS 7应用开发入门经典》(难度指数:※※)
3、《iOS开发指南-0基础到AppStore上架》(难度指数:※※※)
4、《iOS编程实战》(难度指数:※※※※)
这里面讲解的很清楚,后面甚至有简单的项目可以练手,这对于看视频教程看恶心的同学是个福音~你可以先做项目遇到不懂的再看视频。
这里我想多说一句,买iOS开发的辅导书千万别买过时太久的,我看以上有答案还推荐iOS4系列丛书呢...拜托现在都什么年代了,现在iOS8教程都要出来了,你iOS6的教程都过时好久了更别提iOS4了...对于新出的swift语言好多人难以选择不知道该学OC好还是Swift好。我个人建议现在学OC,一门新语言的诞生需要经过时间的考验与洗礼。等你学好了OC以后再看也不迟。
第三阶段及以后
到这个阶段你应该拥有了充分的自学能力,已经达到了入门水平。
这时候以下网址将成为你的家常便饭:
Github,StackOverFlow
如果你编程遇到困难,在StackOverFlow上面应该都能找到合适的解答。(前提是你英文不要太差)。Github上好多开源代码足够丰富你的眼界。如果你想成为一个iOS开发者的话这上面两个网站是你经常以及必须会用到的。
Github上怎么搜牛人们的项目:
img src="" data-rawwidth="425" data-rawheight="360" class="origin_image zh-lightbox-thumb" width="425" data-original=""
想学一点UI的同学可以看:
1、iOS by Tutorials
2、design+code 网址:
想学一点动效/交互的同学可以看:
1、下载QuartzComposer及相关插件如Origami,教程: Quartz Composer学习
想学applewatch开发的同学可以看:
1、《watchKit》raywenderlich刚推出这个教程,英文版无译文。
进价书单:
1、《Effective Objective-C 2.0》(必看)
2、《Objective-C高级编程 iOS与OS X多线程和内存管理》
3、《iOS开发进阶》
4、《iOS Auto Layout 开发秘籍》
推荐博客及网站:
1、Github:
2、StackOverFlow:
3、Code4App:
4、cocoachina:
5、objc中国:
进阶博客(排名不分先后..)
1、王巍的博客(我们都叫它喵神,他很萌哒)
链接: (难度指数:※※※※※)
理由:他的swift的新书讲解的非常好,但不适合入门,进阶的话这是很适合的一本书。其他关于OC的内容可以翻看喵神的博客。
2、唐巧哥的技术博客
链接: iOS开发如何提高 (难度指数:※※※※※)
理由:据传说是iOS圈的刘德华。巧哥05年1月会出一本进阶的书,可以关注以下。
3、叶孤城的技术博客 :
链接:叶孤城带你读源码之RESideMenu (难度指数:※※※)
理由:叶孤城童鞋的风格就是讲解细腻,通俗易懂。
4、破船之家:
链接:beyondvincent.com 的页面 (难度指数:※※※)
理由:破船的博客内容很全面,一些开发笔记,技巧他都会教给你。
5、Xcode Dev
链接: Xcode Dev (难度指数:※※※※)
理由:也是一位大神的原创博客,内容很值得学习。
6、txx's 的博客(我们都叫它虾神,他也超萌哒)
链接: txx's blog
理由: 90后非常优秀的iOS开发者,看看他的大学时期的经历才发现我们过的是多么懈怠,大神之所以为大神也是有原因的。
7、Kevin的博客
链接: Kevin Blog
理由:周楷雯是一个非常厉害的90后iOS开发者,他前些年写的项目在Github上拥有2500+star (PNchat?忘了)非常恐怖。
8、念茜姐姐的blog
链接: 新博客: 旧博客:念茜的博客
理由: iOS圈里的女神级人物,她写的iOS安全类的文章非常值得一看。
9、孙源的blog
链接: sunnyxx的技术博客
理由:90后iOS开发者,技术同样非常强,目前似乎在百度知道任职。
等等...iOS圈内值实力很强又懂得分享知识的开发者绝不止以上几位,我随时想到随时再补充。
(二)swift语言开发iOS应用
这里推荐两个入门学习比较好的方法
1、的网站(难度指数:※)
非常浅显易懂的入门级swift教程:
这个网站可以看两方面:
(1)、随时更新的swift tips (有一定水平在看)
(2)、新手主要看以下这本书img src="" data-rawwidth="390" data-rawheight="434" class="content_image" width="390"
2、《Swift Tutorials》 依然是raywenderlich出品,目前只有英文版。(难度指数:※)
3、官方swift译文教程 《The Swift Programming Language》中文版 (难度指数:※※)
4、上文提到的王巍的博客(喵神)《Swifter - 100 个 Swift 必备 tips》(难度指数:※※※※)
喵神的这本书网上就有售卖,请支持正版,绝对是不可多得的进价书籍,此书并非传统意义上的教程,是以tip的方式呈献给大家的。
记录器
基于不同的场景提供关于记录的封装、适配。一般分为页面式,流式,自定义式。
记录管理者
管理统计记录数据,包含记录缓存,磁盘存储,上传器。
如何降低数据的丢失率?
两种解决方案:
记录上传的时机
上传时机的选择
从三个方面分析架构设计:整体架构、数据流、反向更新。
View 的功能包含:控件的初始化、设置数据、交互事件代理等。
ViewController 的功能:视图创建与组合、协调逻辑、事件回调处理等,事件回调处理指的是视图层的事件。
业务逻辑处理(预排版)、数据增删改查封装者、线程安全处理。
网络请求、数据解析、增删改查、本地处理逻辑(适配)
数据流包含:网络数据、业务数据、UI数据三部分。
网络数据经过 Engine 层处理加工产生业务数据,业务数据经过 ViewModel 层处理产生UI数据,UI数据会转交给视图控制器控制视图的显示。
用户交互网络刷新等都会导致视图层变化,通过代理方式通知视图控制器。控制器对ViewModel的强引用找到对应ViewModel,然后通过UI数据对业务数据的弱引用找到对应的业务数据同时打上脏标记。最后ViewModel进行数据流的重新驱动,将脏数据重新处理生成新的UI数据更新视图。
本节梳理时长统计实现原理和复杂页面的架构实现思路。
学了OpenGL,OpenGLES后,去阅读了GPUImage的源码,使用了一段时间,接下来,记录一下我对GPUImage使用和源码阅读的一些分析吧。
相关引用
从0打造一个GPUImage(6)-GPUImage的多滤镜处理逻辑
对于GPUImage,可以分为
上面也提了,所谓的GPUImage滤镜链就是
GPUImageOutput - filter - filter - GPUImageInput
GPUImageOutput 通过target数组(里面都是实现 GPUImageInput 组件),组成了滤镜链的关系,我们需要牢牢的记住这个滤镜链的关系,这样开发的时候,我们就知道如何Debug,如何实现我们需要的效果。那么问题来了,为什么GPUImage可以实现这样的滤镜链呢?
这里我们先抛开GPUImage,用OpenGL ES去实现一个具有滤镜叠加效果的Demo,这里的Demo我是参考叶孤城的这篇文章, 从0打造一个GPUImage(6)-GPUImage的多滤镜处理逻辑
Demo需要实现的效果,是将一张图片,先后通过叠加 亮度滤镜 , 饱和度滤镜 最后显示在屏幕上。
那么对应的OpenGLES,我们会怎么做呢?首先我们需要以下东西
从以上的步骤,我们可以总结以下结论
对于这个Demo的一个流程图,可以参考 从0打造一个GPUImage(6)-GPUImage的多滤镜处理逻辑 的一幅图,Demo的详细实现请看原文吧。
以上就是GPUImage对于滤镜链的实现原理,只有你懂了OpenGL ES的渲染流程,才能彻底的明白GPUImage的滤镜链的原理。所以时时刻刻记住以下关系
GPUImageOutput - filter - filter - GPUImageInput
当然也可以存在多个Source,多个Input的情况,例如要给一个视频添加水印,用 GPUImageMovie 用于输出视频纹理,用 GPUImageUIElement 输出UI空间的纹理,通过一个filter进行Blend,最后用一个 GPUImageView 进行预览,用 GPUImageMovieWriter 进行输出,滤镜链关系如下
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流