Swift之代码优化

本文内容学习自DamonLu的文章,写在CSDN中为了自己后续学习swift时方便查看,原文地址 https://juejin.cn/post/7028506186743808008,如有侵权告知必删

引言

Swift有很多语言所没有的独特的结构和方法,因此很多刚开始接触Swift的开发者并没有发挥它本身的优势

有条件的for循环

view.subviews中的UIButton做一些处理,用for循环怎么来遍历呢?
在下面的写法中,更推荐后面两种写法:

// ❌
for subView in view.subviews {
	if let button = subview as ? UIButton {
		//待处理的事情
	}
}
// ✅
for case let button as UIButton in view.subviews {
	//待处理的事情
}
//✅
for button in view.subviews where button in UIButton {
	//待处理的事情
}

enumerated()

在swift中进行for循环,要拿到下标值,一般的写法要么 定义局部变量记录下标值,要么 遍历 0…<view.subviews.count 。其实还有个更方便的写法:enumerated(),可以一次性拿到下标值和遍历的元素。


//❌第一种不推荐,因为要定义额外的局部变量,容易出错
var index:Int = 0
for subview in view.subviews {
	//待处理的事情
	index += 1
}
//❌第二种在只需要用到下标值的时候可用,但如果还要用到下标值对应的元素,就还得再取一次,
for index in 0..<view.subviews.count {
	let subview = view.subviews[index]
	//待处理的事情
}
//✅第三种完美,虽然一次性可以拿到下标值和元素,但其中一个用不到就可以用 _

//index和subview在循环体中国呢都能使用到
for(index,subview) in view.subviews.enumerated() {
	//待处理的事情
}
//只用到index
for (index,_) in view.subviews.enumerated {
	//待处理的事情
}
//只用到subview
for (_,subview) in view.subviews.enumerated {
	//待处理的事情
}

first(where:)

filter是swift中几个高级函数之一,过滤集合中的元素时非常的好用,不过在某些情况下,比如获取集合中满足条件的第一个元素时,有一个更好的选择first(where:)

let article1 = ArticleModel(titile:"11",conteng:"内容1",articleID:"1111",comments:[])

let article1 = ArticleModel(titile:"22",conteng:"内容2",articleID:"2222",comments:[])

let article1 = ArticleModel(titile:"33",conteng:"内容3",articleID:"3333",comments:[])

let articles = [article1,article2,article3]

//❌
if let article = articles.filter({$0.articleID == "1111"}).first {
	print("\(article.title)-\(article.content)-\(article.articleID)")
}

//✅
if let article = article.first(where:{$0.articleID == "1111"}) {
	print("\(article.title)-\(article.content)-\(article.articleID)") //11-内容-1111
}

contains(where:)

这个和上面的first(where:)几乎一样,比如这里要判断文章列表里是否包含articleID为1111的文章:

//❌
if !articles.filter({$0.articleID == "1111"}).isEmpty {
	//待处理的事情
}

//✅
if articles.contains(where:{$0.articleID == "1111"}) {
	//待处理的事情
}

forEach

当循环体内的逻辑比较简单时,forEach往往比for…in…来的更加简洁:

func removeArticleBy(ID:String) {
	//删库跑路
}

//❌
for article in articles {
	removeArticleBy(ID:$0.articleID)
}
//✅
articles.forEach{ removeArticleBy(ID:$0.articleID) }

计算属性 vs 方法

我们知道计算属性本身不存储数据,而是在 get 中返回计算后的值,在 set 中设置其他属性的值,所以和方法很类似,但比方法更简洁。一起来看下面的示例:

class YourManager {
    static func shared() -> YourManager {
        //待处理的事情
    }
}

let manager = YourManager.shared()extension Date {
    func formattedString() -> String {
        //待处理的事情
    }
}

let string = Date().formattedString()class YourManager {
    static var shared: YourManager {
        //待处理的事情
    }
}

let manager = YourManager.shared

✅
extension Date {
    var formattedString: String {
        //待处理的事情
    }
}

let string = Date().formattedString

协议 vs 子类化

尽量使用协议而不是继承。协议可以让代码更加灵活,因为类可同时遵守多个协议。

此外,结构和枚举不能子类化,但是它们可以遵守协议,这就更加放大了协议的好处

Struct vs Class

尽可能使用 Struct 而不是 Class。Struct 在多线程环境中更安全,更快。
它们最主要的区别, Struct 是值类型,而 Classe 是引用类型,这意味着 Struct 的每个实例都有它自己的唯一副本,而 Class 的每个实例都有对数据的单个副本的引用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值