IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 面向协议编程 -> 正文阅读

[移动开发]面向协议编程

简单概述

面向对象 OOP 面向协议POP

是Swift的一种编程范式,官方API和一些第三方库用的挺多的,即使不用这种范式,也有了解的必要

相较于OC的delegate,Swift无疑要更强大,从实际开发着手,哪怕是最基本的类也会继承个NSObject,所以会出现两个类在不同的继承分支上,因为Swift的继承是会拷贝一份父类的变量和一些信息,如果全写成NSObject的拓展,那每个子类都会多拷贝很多东西,这样内存开销就会大很多了,OC是创建新的类或者模块,去单独干这件事,然后这种地方只是负责调用,Swift的协议有点类似于这种,但又不同

举个例子:

import UIKit
public protocol sthDelegate
{
    
}
extension sthDelegate
{
    
}
class HomeVC: UIViewController ,sthDelegate {
    
}
class MineView:UIView ,sthDelegate {
    
}

HomeVC和MineView有某些共性,但不能在底层上写,因为会影响所有的View和VC,那么创建一个协议,然后用extension直接做对应的操作即可

利用面向协议添加属性

同时协议也不止这些,还有更牛掰的功能,比如添加属性

例子:

let str = "abc积分换地方叫对方吧由11234"
func hanziCount(str: String) -> Int {
    var count = 0
    for c in str where ("\u{4E00}" <= c  && c <= "\u{9FA5}") {
        count += 1
    }
    return count
}
print(hanziCount(str: str))

这是一个判断汉字数的函数,如果把它拓展到string里面去

extension String
{
    var hanziCount :Int {
        var count = 0
        for c in self where ("\u{4E00}" <= c  && c <= "\u{9FA5}") {
            count += 1
        }
        return count
    }
}
print("abc积分换地方叫对方吧由11234".hanziCount)

但这样就是面向对象了,面向协议可以解决的更细致

struct YK {
    var str :String
    init(_ string :String) {
        self.str = string
    }
    var hanziCount :Int {
        var count = 0
        for c in self.str where ("\u{4E00}" <= c  && c <= "\u{9FA5}") {
            count += 1
        }
        return count
    }
}

extension String
{
    var yk :YK { YK(self) }
}

print("abc积分换地方叫对方吧由11234".yk.hanziCount)

比如这样,可以把扩充的属性进行进一步分类,如果这样还不细,还有更细的,假如两个类有公共的属性,也有不同的,可以更进一步的细化

struct YK<YK_OBJ> {
    var obj :YK_OBJ
    init(_ obj :YK_OBJ) {
        self.obj = obj
    }
    
}
extension YK where YK_OBJ == String
{
    var hanziCount :Int {
        var count = 0
        for c in (self.obj as! String) where ("\u{4E00}" <= c  && c <= "\u{9FA5}") {
            count += 1
        }
        return count
    }
}

extension YK where YK_OBJ == Person
{
    
}
struct Person
{
    var name:String
}

extension Person
{
    var yk :YK<Person> { YK(self) }
}

extension String
{
    var yk :YK<String> { YK(self) }
}
print("abc积分换地方叫对方吧由11234".yk.hanziCount)

使用泛型,然后再区分这个模块,我是觉得有共性就好,详细区分还不如再写个

像上面这样,就有个特点,就是再多个类,又得再写个extension,即使不拓展,也得在每个类里面加一句

var yk :YK<String> { YK(self) },这就很没必要了啊,本来是一模一样的代码,没必要反复写N次啊

struct YK<YK_OBJ> {
    var obj :YK_OBJ
    init(_ obj :YK_OBJ) {
        self.obj = obj
    }
}
extension YK where YK_OBJ == String
{
    var hanziCount :Int {
        var count = 0
        for c in (self.obj as! String) where ("\u{4E00}" <= c  && c <= "\u{9FA5}") {
            count += 1
        }
        return count
    }
}

extension YK where YK_OBJ == Person
{
    
}
//新增
public protocol YKable{}  
extension YKable         
{
    var yk :YK<Self> { YK(self) }
}
//新增

struct Person:YKable
{
    var name:String
}
extension String:YKable {}
print("abc积分换地方叫对方吧由11234".yk.hanziCount)

只要让这些遵守一个协议,然后在协议里面拓展上这段新增代码就好了

以上就是利用协议编程 扩展属性,并给属性加上前缀

利用协议编程进行类型判断

func isArray(_ v: Any) -> Bool { v is [Any] }
print(isArray(["1",1])) //true
print(isArray([2,3])) //true
print(isArray(NSArray())) //true
print(isArray(NSMutableArray())) //true
print(isArray(1))  //false

这是普通的类型判断,一般写程序就会这么写,但如果传入的是类型,而不是一个实例

func isArrayType(_ type: Any.Type) -> Bool { type is [Any].Type }
print(isArrayType([Int].self))    //false
print(isArrayType([String].self)) //false
print(isArrayType(NSArray.self)) //false
print(isArrayType(NSMutableArray.self)) //false
print(isArrayType(Int.self)) //false

这样就完全不能判断了,如果在里面单独进行区分判断也不是可以,但显然更麻烦,让他们遵守某个协议,再判断是否遵守这个协议要更方便些,比如:

protocol Arrayable { }
extension Array :Arrayable {}
extension NSArray :Arrayable { }
func isArrayType(_ type: Any.Type) -> Bool { type is Arrayable.Type }
print(isArrayType([Int].self))              //true
print(isArrayType([String].self))           //true
print(isArrayType(NSArray.self))            //true
print(isArrayType(NSMutableArray.self))     //true
print(isArrayType(Int.self))                //false

这样甚至可以判断各种元组,比如判断是否能遍历的,或者某些有共性的

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-18 10:17:43  更:2021-09-18 10:19:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 11:19:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码