Swift2.0中引入了协议扩展的特性,并且建议开发者一切从协议(Protocol)出发,经过几个月的学习探索,博主发现Swift作为一门面向协议编程(POP)的语言非常适合时下火热的MVVM架构。MVVM已经提出有一段时间了,如果你还不懂什么是MVVM,建议先去补充相关的知识,再回到本文中。
在Cocoa Touch体系内,MVC是广为人知的经典架构,博主之前也讲解过MVC的相关知识,但是随着业务逻辑的扩张,控制器中的代码可能会变得非常庞大导致难以维护,因为无论是OC还是Swift都是单类继承,这就使得类的世界总是处于一个垂直的继承链中。
而在2.0版本之前的Swift版本中,协议中的成员无法进行初始化,只存在一个声明,这就造成了代码复用上的困难。好在Swift2.0中引入的协议扩展,使得协议可以通过扩展的方法赋予默认的实现,并且通过where语法为不同的协议组合赋予不同的初始格式,controller可以通过简单的遵循某个协议,而获得协议中定义好的方法,直接使用,大大缓解了控制器的压力,不会造成臃肿的继承关系。
另外虽然MVC中的view和controller应该是松散的,但在实际开发中我们都知道,view和controller的结合非常紧密,大量处理view的代码都会写在controller中,会对Debug的定位造成一定的困扰。
基于以上的问题,为针对iOS代码解耦和的MVVM框架日渐火热,结合Swift2.0中的协议扩展特性可以写出非常悦目的代码。具体请看下面的示例,在一个非常常见的商品展示的TableView中,传统的做法大抵如下:
你需要一个继承一个TableViewCell的基类,然后在storyboard中设计好你的页面,再把页面与代码的元素关联起来:

class ShowedTableViewCell: UITableViewCell {

    @IBOutlet weak var showedImage: UIImageView!
@IBOutlet weak var NameLabel: UILabel!
@IBOutlet weak var priceLabel: UILabel!
func configCell(showedImageView:UIImageView,Name:String,price:String){...}
...
}

而工程中商品对应的数据模型(Modal)中保存了商品信息的数据结构,名称、价格、第三方平台上保存的图片地址等等。

class Something {
var name:String?
var price:String?
var imageViewURL:String?
}

这些信息需要提供给Cell做展示,此时你会发现定义完数据结构之后似乎就没Modal啥事了,你会打开熟悉的Controller代码,在里面关联一张tableview,运用封装的网络通信方法获取Modal中需要的信息,保存在controller中的临时数组[Something]中,最后筛选出相应的信息在tableview的datasource方法和delegate中运用传递。这一切似乎顺理成章,但是如果你的controller对应的是某个商城的首页,首页中除了tableview可能还有navigation、slider、collectionView等等,那么你的controller代码会变得非常臃肿,Boooom!~
上面的示例运用POP+MVVM是这样的:
1.首先编写一个用来传递数据的协议,这个协议中的方法按照需要传递的数据类型来命名,参数为可变参数,本例中的代码如下:

protocol RenderContext{
func renderText(texts:String...)
func renderImage(images:UIImage...)
//func renderInt、renderDouble...
}

注意这里我们虽然只用到了String和UIImageView类型,但实际协议中的方法不需要局限于这两个类型,你可以通过协议扩展的规则来复用这个协议。
2.定义反向的数据传递:

protocol ViewModal{
func contextInRender(context:RenderContext)
}

3.在相应的场合中扩展上面的协议,使得协议中的方法获得实现:

extension ShowedTableViewCell:RenderContext{
func renderText(texts: String...) {
NameLabel?.text = texts.first
priceLabel?.text = texts.last
}
func renderImage(images: UIImage...) {
showedImage.image = images.first
}
}
extension Something:ViewModal{
func contextInRender(context: RenderContext) {
context.renderText(name!,price!)
context.renderImage(UIImage(data: NSData(contentsOfURL: NSURL(string: imageViewURL!)!)!)!) }
}

View和Modal彼此通过两个协议进行交互,这个写法的灵感来自2016Swift大会上做分享的大神傅若愚,没有引入新的代码层次,博主会在新的工程中继续实践这种新的MVVM模式,带来更多的分享。

参考链接:http://www.2cto.com/kf/201603/491507.html

Swift POP+MVVM的更多相关文章

  1. Swift -POP( 面向协议编程)与OOP(面向对象编程)

    面向协议编程(Protocol Oriented Programming,简称POP),是Swift的一种编程范式,Apple于2015年WWDC提出的,如果大家看Swift的标准库,就会看到大量PO ...

  2. iOS仿抖音节拍界面、Swift,MVVM架构完整项目、日历demo、滚动切换分类等源码

    iOS精选源码 在Object-C中学习数据结构与算法之排序算法 日历-基本功能都有的日历 选择日期 上下月 动画 仿抖音卡节拍界面 垂直.水平方向皆可滚动.header悬浮的列表视图 Auto La ...

  3. swift pop实现动感按钮动画

    // //  MyButton.swift //  PopInstall // //  Created by su on 15/12/11. //  Copyright © 2015年 tian. A ...

  4. swift -pop的简单动画

    //1.新建空文件  命名Podfile //2.写入 pod ‘pop’,’~>1.0’  保存 //3.打开终端,进入项目路径 执行pod install //4.新建桥接头文件 导入#im ...

  5. Swift & OC 混编 浅析

    转载自:http://www.infoq.com/cn/articles/wangyi-cartoon-swift-mixed-practice?utm_campaign=rightbar_v2&am ...

  6. 自定义AlertView(Swift)

    MyAlertView.swift // Pop Up Styles enum MyAlertViewStyle: Int { case success case error case notice ...

  7. 第18月第2天 ios博客

    1. github https://githuber.cn/search?language=Objective-C https://www.jianshu.com/u/815d10a4bdce htt ...

  8. Swift建立栈的泛型结构体以及top()、push()、pop()定义函数的定义

    首先可以使用swift定义Stack的结构体 //泛型表达 struct Stack<T> { var items = <T>() //定义栈顶函数,返回栈顶元素 mutati ...

  9. Swift 玩转 3D Touch 之 Peek & Pop

    什么是3D Touch 3D Touch 是iOS9之后专为 iPhone6s 机型加入的新特性,这一新技术移植于 Mac Book 上的 ForceTouch 更准确地说应该是 ForceTouch ...

随机推荐

  1. 经典dp 编辑距离

    给定两个字符串S和T,对于T我们可以进行三种操作 (1)在任意位置增加字符 (2)删除字符 (3)替换字符 问最少多少次能把T变成S? 设f(i,j)是S的前i位和T的前j位对齐的最小花费 接下来分析 ...

  2. layoutSubview触发时机

    layoutSubviews在以下情况下会被调用: 1.init初始化不会触发layoutSubviews 2.addSubview会触发layoutSubviews 3.设置view的Frame会触 ...

  3. CSS的基本概念

    <!--CSS 一.概念:CSS的全称是Cascading Style Sheets,层叠样式表,用来控制HTML标签样式,在美化网页中起到非常重要的作用 CSS的编写格式是键值对形式的,比如 ...

  4. Html复杂表头的实现

    实现效果 代码实现

  5. 新学的js精集

    逻辑运算符比较 逻辑与和逻辑或这两个逻辑运算符它不单单会输出布尔型数据 1.只要"||"前面为false,无论"||"后面是true还是false,结果都返回& ...

  6. while循环与i--

    int i = 5;         while(i-- > 0){             System.out.println("i="+i);         } 打印 ...

  7. 【转载】将绿色版Tomcat服务添加到系统服务并设为开机运行

    转自: http://www.cnblogs.com/lan0725/archive/2009/11/04/1873859.html   运行cmd打开控制台,进入Tomat目录/bin文件夹,输入如 ...

  8. APK重新签名方法

    Android使用SHA1-RSA算法进行签名.可通过eclipse插件进行,可以通过keytool和jarsigner 用命令行执行,也可以在源码下进行签名. 第一种:通过使用eclipse进行签名 ...

  9. Loadrunner中参数和变量的使用

    //字符串复制strcpy(str,"Hello ") ; //字符串连接strcat(str,"World !");lr_message("str: ...

  10. 使用CodeFirst实现动态建库

    一.业务分析 以我们平时注册今目标为例,我们在注册今目标的过程中,具体步骤是这样的: 图1 今目标登陆流程 详细解释一下: 第一步:注册界面.输入手机号或者邮箱,点击确定进入基本信息界面. 第二步:基 ...