普通视图

发现新文章,点击刷新页面。
昨天 — 2025年6月27日首页

Swift 6 新特性(一):count(where:) 方法带来的从复杂到简洁变化

作者 iOS新知
2025年6月27日 12:47

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

Swift 语言一直在不断演进,推出的新特性不仅提升了性能,还提高了代码的可读性。

其中一个值得关注的新功能就是在 SE-0220 中引入的 count(where:) 方法。这个方法让我们可以更高效、更具表现力地统计序列中满足特定条件的元素,避免了之前需要结合 filter()count 的复杂操作。

count(where:) 方法将过滤(filter)和计数(count)两个步骤合并为一个,省去了创建和丢弃中间数组的麻烦,从而提升了性能,同时代码也变得更加简洁。

示例1:统计高于冰点的温度

假设我们有一个以摄氏度为单位的温度数组,我们想统计其中有多少温度高于冰点(0°C):

在之前,我们可能需要这样写:

let temperatures = [-510, -22025, -1]
let aboveFreezingCount = temperatures.filter { $0 > 0 }.count

现在,我们可以使用 count(where:) 方法来简化代码:

let temperatures = [-510, -22025, -1]
let aboveFreezingCount = temperatures.count { $0 > 0 }

// 输出 `3`
print(aboveFreezingCount)

在这个例子中,aboveFreezingCount 的值为 3,因为有三个温度(10, 20, 25)符合条件。

示例2:统计具有特定前缀的元素

让我们再看一个示例,假如我们有一组产品名称,想统计以 "Apple" 开头的产品数量:

let products = [
    "Apple", 
    "Banana", 
    "Apple Pie",
    "Cherry", 
    "Apple Juice", 
    "Blueberry"
]
let appleCount = products.count { $0.hasPrefix("Apple") }

// 输出 `3`
print(appleCount)

在这个例子中,appleCount 的值为 3,因为 "Apple"、"Apple Pie" 和 "Apple Juice" 都以 "Apple" 开头。

示例3:根据长度统计元素

一个常见的应用场景是根据元素的长度进行统计。例如,我们可能想知道数组中有多少名字的长度少于六个字符:

let names = ["Natalia""Liam""Emma""Olivia""Noah""Ava"]
let shortNameCount = names.count { $0.count < 6 }

// 输出 `4`
print(shortNameCount)

在这个例子中,shortNameCount 的值为 4,因为 "Liam"、"Emma"、"Noah" 和 "Ava" 的长度都少于六个字符。

示例4:统计特定元素

如果需要统计序列中某个特定元素出现的次数,可以在闭包中使用等于运算符 (==)。例如:

let animals = ["cat""dog""cat""bird""cat""dog"]
let catCount = animals.count { $0 == "cat" }

// 输出 `3`
print(catCount)

在这个例子中,catCount 的值为 3,因为 "cat" 在数组中出现了三次。

适用范围和平台支持

count(where:) 方法适用于所有遵循 Sequence 协议的类型,这意味着我们不仅可以在数组中使用,还可以在集合、字典和其他序列类型中使用。

但需要注意的是,序列必须是有限的,以确保方法能够在合理的时间内完成。

count(where:) 方法在 Swift 6 中引入,因此需要 Xcode 16 才能使用这个特性。它支持多种平台和操作系统版本,包括 iOS 8.0+、macOS 10.10+、visionOS 1.0+ 等。

总结

count(where:) 方法是一个非常实用的功能,它不仅简化了代码,还提高了性能。如果你是一名经验丰富的 Swift 开发者,想要学习高级技巧,可以关注我的公众号,我会持续分享 Swift 相关的技巧和知识。

你对这个新特性有什么看法呢?欢迎在评论区与我们分享你的想法。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

Xcode 高效秘诀:这 11 个快捷键你必须知道!

作者 iOS新知
2025年6月26日 20:02

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

作为一个 iOS 开发者,在使用 Xcode 时,掌握键盘快捷键是提高生产力和效率的关键。在这篇文章中,我将为大家介绍一些我最喜欢的 Xcode 快捷键。

其实之前也写过一些相关的文章,感兴趣的也可以去看看:

快捷键速查表

在开始之前,先来一个快捷键速查表:

  • ⌘ - Command

  • ⇧ - Shift

  • ⌥ - Option/Alt

  • ⌃ - Control

现在,让我们一起深入了解吧。

1. 产品菜单快捷键

首先,让我们从 Xcode 的产品菜单中一些基础快捷键开始:

  • 运行:⌘ R

  • 测试:⌘ U

  • 清理构建文件夹:⇧ ⌘ K

  • 清理 DerivedData 文件夹:⌘ ⇧ K

  • 停止:⌘ .

如果你已经是一个 iOS 开发者了,相信这些快捷键你已经很熟悉了,下面我们再介绍一些更高级的快捷键。

2. 快速导航

在处理不同文件,或者跟踪调用栈来解决问题时,快速导航是节省时间的法宝:

  • 前进:⌃ ⌘ →

  • 后退:⌃ ⌘ ←

3. 快速打开与跳转定义

另一个重要的快捷键是快速打开文件,使用 ⇧ ⌘ O,这个快捷键不仅可以搜索文件,还可以搜索类名和方法。

image.png

使用此快捷键后,跳转到定义,然后如果你想知道当前方法的所在的文件,可以使用 ⌃ ⌘ J 快捷键。

4. 查找功能

无论是在当前打开的文件中,还是在整个项目/工作区内,查找都是必不可少的操作:

  • 当前文件查找:⌘ F

  • 当前文件查找并替换:⌥ ⌘ F

  • 全局查找:⇧ ⌘ F

5. 视图管理

能够快速显示和隐藏不同的 Xcode 区域特别有用,尤其是在较小屏幕上工作时:

  • 显示/隐藏项目导航器:⌘ 0

  • 显示/隐藏调试控制台:⌘ ⇧ Y

  • 显示/隐藏检查器:⌘ ⌥ 0

6. 快速打开两个文件并排显示

我之前提到过的快速打开命令 ⌘ ⇧ O,在结合使用 ⌥ 时更加强大。

  • 使用 ⌘ ⇧ O 打开对话框

  • 输入你要查找的文件名

  • 按住 ⌥ 键然后用鼠标单击目标项目,或者使用 enter 键选择文件。新文件将会在一个单独的编辑器中打开,这样你可以继续在当前文件上工作,同时访问新打开的文件。

这个 ⌥ 技巧在项目导航器中选择文件时也同样适用。

7. 快速跳转到文件中的特定方法

对于大型文件中有众多方法的情况,这个快捷键非常有用,因为滚动很快会变得繁琐。

  • 使用 ⌃ 6 打开文档结构

  • 开始输入方法名

  • 使用 enter 键跳转到该方法

image.png

在输入时还可以模糊匹配,Xcode 会为你完成搜索。

8. 重复上一次测试

如果你经常写单元测试,快捷键 ⌃ ⌘ ⌥ G 在特别有用,可以重复运行我们上次进行的测试。

9. 重新缩进代码

我们可以通过按 ⌃ I 来重新缩进选定的代码,这在代码位置混乱时(例如在重构之后)特别有用。

我一般会配合全选快捷键 ⌘ A 一起使用,先全选再重新缩进,这样就可以将整个文件的代码进行重新缩进了。

10. 启用/禁用断点

在调试代码时,快捷键 ⌘ Y 可以帮助我们快速启用和禁用断点。

11. 不编译运行

这个快捷键非常有用,但可能很多人不知道。

在开发过程中,我们通常使用 ⌘ R 来运行代码,但这个命令其实是先编译再运行,但有时候我们并不需要编译,比如我刚执行完 ⌘ B,或者刚刚运行完没改代码的情况下想再运行一次。

这时候就可以使用 ⌃ ⌘ R 快捷键,直接运行,不用重新编译,非常节省时间。

总结

通过掌握这些快捷键,你可以大大提高在 Xcode 中的工作效率,节省宝贵的时间,让开发过程更加顺畅。希望这些快捷键能为你的开发旅程带来更多便利,你还有哪些喜欢的快捷键,欢迎在评论区留言分享。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

昨天以前首页

惊人发现!Swift 循环性能对比,你用对了吗?

作者 iOS新知
2025年6月25日 13:24

这里每天分享一个 iOS 的新知识,快来关注我吧

image.png

前言

在 Swift 编程中,我们经常需要使用循环来处理数据,那么你有没有想过哪些循环函数的性能最好?

今天我们随便挑几个循环函数来测一下性能。

for 循环、while 循环和高阶函数 reduce 的性能表现如何呢?让我们通过一个简单的性能测试来一探究竟。

性能测试代码

我们使用以下代码来测量不同循环结构的执行时间,如果你想测试其他的循环方法,也可以参考这个代码:

func processTime(_ title: String, closure: () -> ()) {
    let startTime = CFAbsoluteTimeGetCurrent()
    closure()
    let duration = CFAbsoluteTimeGetCurrent() - startTime
    print(title, "Duration = \(String(format : "%.4f", duration))")
}

processTime("for-in") {
  var sum = 0
  for i in 0..<10000000 {
    sum += i
  }
}

processTime("while") {
  var sum = 0
  var i = 0
  while i<10000000 {
    sum += i
    i += 1
  }
}
        
processTime("reduce") {
  let sum = (0..<10000000).reduce(0, +)
}

测试结果

在 Debug 模式下运行上面的代码,结果如下:

  • for-in Duration = 1.5586 秒

  • while Duration = 0.0115 秒

  • reduce Duration = 1.5766 秒

看到这个结果,我不禁好奇,为什么 for 循环和 reducewhile 循环慢这么多呢?

深入分析

for-in 循环分析

通过使用 Profiler Instruments 工具,我们可以更深入地了解 for-in 循环在底层的运作:

Image

  • for 循环被转换为 IndexingIterator

  • 每次调用下一个索引时,都会触发 next() 函数(97% 的时间都花在调用 next() 函数上)。

  • 每次触发 next() 时,它会调用一系列协议方法(动态调度),这需要时间去查找协议表。

为什么 next() 函数使用动态调度呢?让我们看看 IndexingIterator 的实现细节:

public protocol CollectionSequence {
    ...
}

public struct IndexingIterator<ElementsCollection> { 
    let _elements: Elements
}

extension IndexingIteratorIteratorProtocolSequence {
    public mutating func next() -> Elements.Element? {
        if _position == _elements.endIndex { return nil }
        let element = _elements[_position]
        _elements.formIndex(after: &_position)
        return element
    }
}

next() 函数中,我们使用了 _elements 属性。由于 _elements 可以是任何 Collection 协议类型,因此在编译时我们并不知道 _elements[_position]_elements.formIndex 指向哪个成员。因此,我们必须在运行时查看虚表并使用协议表。

相比之下,while 循环只需管理一个参数,不需要执行任何表查找。因此,while 循环的工作量更少,性能自然比 for-inreduce 更好。

Swift 编译器探索

我们还可以使用 godbolt 工具来查看代码的编译方式:

在编译时,Swift 会将 for-in 转换为:

let range: Range<Int> = 0..<10000000
let iterator = range.makeIterator()
while iterator.next() {
  ...
}

Image

Release 模式下的表现

在 Release 模式下,开启编译器优化后,结果如下:

  • for-in Duration = 0.0063 秒

  • while Duration = 0.0053 秒

  • reduce Duration = 0.0075 秒

在编译器优化开启的情况下,Swift 不需要执行一堆动态调度。它只需管理一个计数器变量,增加它的值并执行求和操作,直到算出结果为止。🚀

学到什么?

  1. Profiler Instrument 是一个调试应用程序性能的有用工具。

  2. 测量应用程序性能时,应在 Release 模式下进行。

  3. 了解了一些关于 Swift 编译器的知识。

总的来说,while 循环在 Debug 模式下表现更好,而在 Release 模式下,开启编译器优化后,各种循环的性能差异变得不明显,表明编译器优化对性能的影响很大。

这提醒我们,在进行性能优化时,必须考虑编译器优化的影响。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

开发者必看,全面解析 iOS 架构,探索 iOS 背后的秘密!

作者 iOS新知
2025年6月24日 11:35

这里每天分享一个 iOS 的新知识,快来关注我吧

image.png

前言

苹果的移动设备,包括 iPhone、iPad 和 iPod,都是运行在 iOS 平台上,虽然后来 iPad 独立拆分出去成为了 iPadOS,但 iOS 和 iPadOS 的底层架构和 iOS 是相同的。

iOS 是基于 Darwin 为基础开发的。iOS 不仅可以管理硬件功能,还提供了开发 iOS 应用所需的一切技术支持。

iPhone 设备的基础软件包中包含一些常用的系统应用,例如邮件、日历、计算器、电话和浏览器等。然而,出于安全和商业原因,不可能在 Apple 以外的任何硬件上运行 iOS 和 Mac OS X,并且禁止在 Apple 以外的任何其他移动设备上使用 iOS。。

但是你有没有想过,iOS 的架构是怎样的?今天我们就来简单了解一下 iOS 的架构,如果未来你有机会研发一个新的操作系统,那么了解 iOS 的架构将对你有很大的帮助。

iOS 架构概述

iOS 架构的分层设计主要分为以下几层,可以从图中看得比较清楚:

image.png

  1. Core OS:核心操作系统层,负责管理硬件设备,提供内存管理、文件系统处理和线程等基本操作系统的功能。

  2. Core Services:核心服务层,将核心操作系统层提供的服务抽象化,提供所有应用可用的基本服务。

  3. Media:媒体层,通过 Media 层,开发者可以使用 iPhone 上的多媒体服务。

  4. Cocoa Touch:Cocoa Touch 层,提供了一个抽象层,使 iPhone 和其他 iOS 设备编程的各种库可访问。

iOS 会讲代码封装到框架(Framework)中。框架通常包括头文件、图片和所有所需的动态共享库。

多数 iOS 开发者在开始开发时倾向于选择更高级别的框架,因为它们提供了面向对象的抽象、更少的代码编写以及封装其他特性的能力。接下来让我们来探讨这些不同的抽象层次。

Core OS

作为 iOS 栈的最底层,Core OS 位于设备硬件之上。它提供了所有 iOS 功能的基础低级特性。除了基本操作系统的标准功能,如内存管理、文件系统处理和线程外,还提供了一些服务,包括低级网络和对外部配件的访问。

核心 OS 层储存了大多数其他技术的底层特性,比如。

  • Core Bluetooth Framework:与传统和低能耗蓝牙设备进行交互。

  • External Accessories Framework:与通过蓝牙或 Apple Lightning 连接的设备配件通信。

  • Accelerate Framework:进行大规模数学和图像计算,优化高性能和低能耗。

  • Security Services Framework:控制对应用及其维护数据的访问。

  • Local Authorization Framework:通过用户熟悉的生物识别或密码进行身份验证。

Core Services

Core Services 层将 Core OS 层提供的服务抽象化,提供所有应用可用的基本服务。核心服务层和其他层一样,提供了一组框架:

  • Accounts framework:允许用户直接从应用访问和管理其外部帐户,而无需输入登录信息。

  • Address Book framework:访问用户的联系信息。

  • CFNetwork framework:管理网络配置更改和网络服务访问。

  • Core Data framework:管理 MVC 应用的数据模型。

  • Core Foundation framework:提供基本数据管理和服务功能的接口。

  • Core Location framework:支持提供应用的位置信息和方向数据。

  • Core Media framework:提供音频和视频的播放、录制和处理。

  • Core Motion framework:提供设备的运动数据。

  • Core Telephony framework:提供电话网络服务。

  • EventKit framework:提供访问日历和提醒数据的功能。

  • Foundation framework:它为应用程序和框架提供了基础功能层,包括数据存储和持久化、文本处理、日期和时间计算、排序和过滤以及网络。对于 iOS 开发来说,Foundation 框架是使用最频繁的框架之一。

  • Mobile Core Services framework:该框架提供对重要操作系统功能的访问和控制。

  • Social framework:这个框架利用通用系统接口,将用户分享内容发布到支持的社交网站。

  • StoreKit:这个框架支持应用内购买以及与 App Store 的交互。

  • System Configuration framework:该框架允许应用程序访问设备上的网络配置选项,检查设备的可达性,例如 Wi-Fi 或蜂窝连接是否处于活动状态等。

Media Layer

通过 Media 层,开发者可以使用 iPhone 上的多媒体服务。主要包括系统的图形、音频和视频技术。苹果特别注重多媒体体验的反馈,尤其是音频和视频质量。所以 iOS 的底层媒体层赋予 iOS 音频、视频、图形和 AirPlay(无线传输)能力。

  • Assets Library framework:这个框架提供对用户资产的媒体库的访问。

  • AV Foundation framework:处理视听资源、管理相机设置、编辑音频并建立系统音频交互。

  • Core Audio framework:与设备的音频硬件接口。

  • Core Graphics framework:iOS 应用的本地绘图引擎,支持自定义 2D 矢量和基于图像的渲染。

  • Core Image framework:为控制视频和照片提供高级无损支持。

  • Core MIDI framework:提供与 MIDI(乐器数字接口)设备通信的 API,包括硬件键盘和合成器。

  • Core Text framework:提供了用于布局文本和处理字体的低级编程接口。

  • Core Video framework:利用基于管道的 API,支持 Metal 和 OpenGL 来处理数字视频,包括逐帧编辑。

  • Image I/O framework:这个框架提供对图像元数据的访问以及读取和写入大多数图像文件类型。

  • GLKit framework:使用硬件加速 API 管理高级 2D 和 3D 渲染。

  • Media Player framework:这个框架可以从应用程序中查找并播放歌曲、音频播客、有声读物和其他媒体。

  • OpenAL framework:这个框架提供了一种行业标准音频传输技术。

  • OpenGL ES framework:该框架通过硬件加速接口控制强大的 2D 和 3D 渲染。

  • Quartz Core framework:该框架允许用户使用幻灯片和 Core Image 滤镜查看、更改和保存照片。

Cocoa Touch

Cocoa Touch 层提供了一个抽象层,使 iPhone 和其他 iOS 设备编程的各种库可访问。Cocoa Touch 层包含了一组使用 Mac OS X Cocoa API 创建的 Objective-C 框架。

任何 iOS 应用的 UI 设计开发都是使用 Cocoa Touch 框架创建的。这一层支持通知、多任务处理、触摸特定输入、所有高级系统服务和其他重要技术。

  • Address Book UI framework:这个框架可以获取用户的联系人并将其呈现在图形界面中。

  • Event Kit UI framework:这个框架是一个用视图控制器来显示和更改事件的通用系统界面。

  • Game Kit framework:该框架允许用户通过游戏中心在线共享游戏相关数据。

  • iAd framework:广告框架。

  • Map Kit framework:地图框架。

  • Message UI framework:消息框架。

  • Twitter framework:用于创建推文以及创建 URL 来访问 Twitter 服务的用户界面。

  • WebKit framework:网页框架。

  • UI Kit framework:为 iOS 图形化、事件驱动的应用开发提供关键基础。

可以说做 iOS 开发,使用最多的就是 Foundation 和 UIKit 两个框架。

另外这一层还提供其他开发者使用的能力,例如:

  • 多任务处理。

  • 基本的应用程序管理和基础设施。

  • 用户界面管理。

  • 处理触摸事件。

  • 剪切、复制和粘贴等。

结论

综上所述,iOS 的架构设计合理,分层清晰,为开发者提供了丰富的框架和接口,使得开发 iOS 应用变得更加高效和便捷。

无论是从底层的 Core OS 到最上层的 Cocoa Touch,每一层都扮演着重要的角色,为用户提供了稳定、高效、安全的移动应用体验。深入了解 iOS 的架构,将有助于开发者更好地理解和利用 iOS 平台的强大功能,为开发出更优秀的应用奠定基础。

iOS 的成功不仅在于其设计和功能,更在于其庞大而完善的生态系统,相信随着技术的不断发展,iOS 将继续引领移动应用开发的潮流,为用户带来更多惊喜与便利。

你对 iOS 的架构有什么看法?欢迎在评论区留言讨论。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

❌
❌