iOS 开发中的一些常见概念和杂项记录
关于 iOS 开发中的一些常见概念的解释以及一些杂项记录.
减小图片的内存占用
如果使用 png 图片, 务必参考之前写过的一篇 关于 iOS 系统下加载网络图片的内存占用问题
来操作, 这样的话图片的内存占用会少 很多.
问题或业务需求点记录
-
如何在一个 Xib 中使用另外一个 Xib 中的内容?
-
Entitlement 文件的作用?
-
Scheme 是什么? 它和 target 之间有什么关系?
这个需要从 target 本身说起, 首先一个项目中可以有多个 target, 每个 target 都对应工程中的一个编译目标, 可以是 app, 也可以是 framework. 即 target 是比 project 更低一级的单位, 一句话讲: 工程中的每个 target 都对应一个产品.
通过 target, 可以从逻辑上组织起一整套用于构建产品的文件集合, 这些文件包括: 源文件, 编译这些源文件所需的配置信息. 而配置信息是以 build settings
和 build phases
的形式呈现的.
工程中的所有 target 都会继承这个工程的 build settings
, 不过这些设置都可以在 target 中被覆盖以设置不同的值.
在开发过程中, 同一时刻只会有一个 target 处于活动状态, 由 Xcode scheme
指定这个活动状态的 target.
故在日常开发中, 通过 Xcode Scheme 来指定当前哪个(或哪些) target, 哪个 build configuration, 以及哪个 executable configuration 是活动的.(即每个 Scheme 都对应了一套 target, build configuration 等配置信息.), 选择哪个 Scheme, 则哪一套就处于活动状态.
- build setting 的组织: Build Configuration
在 Xcode 中, project 级别的 build setting 会被所有内部的 target 的 build setting 继承. 而一套 build setting 对应的就是一个 build configuration, 在 Xcode 中总是自动预定义了两套 build configuration, 一套是 debug, 一套是 release.
开发者可以针对 target 产品的需要对其设置其他的 build configuration, 这样就可以针对不同场景来对对应的 target 进行配置.
-
关于 Target, Scheme, Project, Workspace, Build Configuration 的内容, 详见苹果官方文档.
-
如何使用 Setting bundle?
-
app group 的作用?
-
xcconfig 文件是什么? 如何使用?
-
如何对应用进行本地化和国际化?
-
Segue 的使用?
-
Swift 中的正则表达式?
-
关于用户输入的验证逻辑: 可以放到对应类型的扩展中去写, 或者是写针对某个业务的 Validator, 然后将数据送入验证. 另外有一个 Validator 库的接口可以作为参考.
-
关于清晰架构 + RxSwift:
-
updateConstraints
方法: 调用某个视图的setNeedsUpdateConstraints()
方法, 之后系统会自动调用updateConstraints
, 从而更新显示, 注意不能在updateConstraints
的实现中调用setNeedsUpdateConstraints
, 且在updateConstraints
的最后一行应该调用super.updateConstraints
. -
Framework Programming Guide, Bundle Programming Guide, Code Size Performance Guidelines, App Sandbox Design Guide, Metal, Launch Time Performance Guidelines, Resource Programming Guide
-
CaseIterable 协议: 提供有默认实现, 任何遵守它的 enum 都获得枚举自身所有 case 的能力.
-
Swift 中单例的实现方式:
// 针对不需要额外配置的情况:
class Singleton {
static let sharedInstance = Singleton()
}
// 针对需要额外配置的情况:
class Singleton {
static let sharedInstance: Singleton = {
let instance = Singleton()
// setup code
return instance
}()
}
- Foundation 框架中有处理进程和线程相关的类, 下面是它们的一些内容:
-
Runloop 类型
: 该类型的对象用于处理外部输入, 输入包括鼠标键盘或 Timer 事件等. 但在应用中无需创建它们, 因为每个线程对象(包括主线程)都由系统自动创建它们对应的 Runloop 对象. 获取当前线程关联的 Runloop 对象, 可以使用current
类方法.但从 Runloop 的角度看 Timer 时, Timer 并非作为一种输入源, 而是一种特殊的类型, 因为 Timer 的触发并不会导致 Runloop 的
return
.在使用时一定注意不要在一个线程中调用另外一个线程关联的 Runloop 对象的任何内容, 因为这样会导致不可预料的结果.
-
Timer 类型
: 定时器会在设定的某个时间段结束后发送消息给某个预定的目标对象.Timer 需要和 Runloop 结合使用, Runloop 会持有它自己的所有 Timer, 故在使用时, 需要将 Timer 添加到 Runloop, 而非在外部去持有 Timer.
但需要注意的是, timer 并非一种实时机制, 如果 timer 当前已经可以触发, 但此时 runloop 没有机会检查 timer, 则 timer 会在 runloop 下次检查 timer 时触发. 故可能当前 timer 触发的时机会比预设的晚很多!
这里就涉及到 DispatchTimer 和 Timer 的区别了: 待了解.
-
NSLock 类型和 NSLocking 协议
: NSLock 使用 POSIX 线程实现它的加锁行为, 故需要在调用lock
的线程中去调用unlock
, 否则结果会不可预料. 另外如果连续调用两次 lock, 则该线程会被永远加锁. 故如果需要递归锁, 要使用NSRecursiveLock
. 另外如果在没有被 lock 的 NSLock 对象上调用 unlock, 则会出现错误, 这本身就是一种编程错误.
常用资源
-
Xcode Help! 多看看 Help 文档, 有空就看, 会有很多收获的!
-
在 这个网站 中可以下载到许多语言或平台对应的 gitignore 文件.
-
Koloda 库, Macaw 库, SwiftOCR 库.
-
图片点击放大滑动查看: SKPhotoBrowser.
-
Swift 清晰架构: 使用 RxSwift 的例子.
-
如果要做视频播放的话, 需要看看 AVFoundation 的内容, 这样不至于什么东西都不知道.
-
MarkdownView 库: 基于 WKWebView 编写的 MarkDown 显示框架.
-
GPUImage 3: 利用 GPU 加速视频和图片处理, 这个库是基于 Metal 编写的.
-
JustHTTP: 一个接口定义十分人性化的 HTTP 请求库, 可以学习一下它的内部结构.
-
Device: 一个判断当前设备类型和版本的库, 可以学习一下它的内部.
-
iOS 开发最佳实践: iOS 开发最佳实践的英文原版, 值得一看. 中文版的在这里.