Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • iOS 学习开发指南
    • iOS 开发入门指南
      • 什么是 iOS 开发?
      • 学习路径建议
      • 🎯 初学者路径(0-3个月)
      • 🚀 进阶路径(3-6个月)
      • 💡 高级路径(6个月+)
      • 开发环境要求
    • 基础知识
      • 开发环境搭建
      • 编程语言基础
      • Swift基础语法
      • Swift 重要特性详解
      • 1. 可选类型(Optionals)
      • 2. 协议(Protocols)
      • 3. 扩展(Extensions)
      • 4. 泛型(Generics)
      • Objective-C基础语法
    • 核心框架
      • UIKit框架
      • 视图控制器
      • 常用UI组件
      • SwiftUI框架
      • 基本视图
      • 常用SwiftUI组件
    • 数据存储
      • UserDefaults
      • Core Data
      • 文件系统
    • 网络通信
      • URLSession
      • WebSocket
    • 多线程和异步编程
      • GCD (Grand Central Dispatch)
      • Operation和OperationQueue
      • async/await (iOS 15+)
    • 内存管理
      • 引用类型
    • 调试和测试
      • 调试技巧
      • 单元测试
    • 应用生命周期
    • 常用第三方库
      • CocoaPods
      • Swift Package Manager
    • 实战项目示例
      • 简单的待办事项应用
      • 数据持久化版本
    • 最佳实践
      • 代码组织
      • 错误处理
      • 性能优化
    • 常见问题解答
      • Q: Swift 和 Objective-C 应该学哪个?
      • Q: 需要 Mac 才能开发 iOS 应用吗?
      • Q: 如何选择 iOS 版本支持?
      • Q: 学习 iOS 开发需要多长时间?
      • Q: 如何提高 iOS 开发技能?
    • 学习资源推荐
      • 📚 官方资源
      • 🎓 在线课程
      • 📱 实战项目
      • 🛠️ 开发工具
    • 总结
    • 链接
  • 调研

  • 其他

  • 《iOS》
Jacky
2025-07-16
目录

iOS 学习开发指南

# iOS 开发入门指南

# 什么是 iOS 开发?

iOS 是苹果公司开发的移动操作系统,为 iPhone、iPad 和 iPod touch 提供支持。iOS 开发主要使用 Swift 和 Objective-C 两种编程语言。

# 学习路径建议

# 🎯 初学者路径(0-3个月)

  1. Swift 语言基础 - 语法、数据类型、控制流
  2. Xcode 使用 - IDE 基本操作、调试技巧
  3. UIKit 基础 - 视图控制器、常用 UI 组件
  4. 简单应用 - 创建第一个 iOS 应用

# 🚀 进阶路径(3-6个月)

  1. UI 设计 - Auto Layout、约束布局
  2. 数据存储 - UserDefaults、Core Data
  3. 网络编程 - URLSession、JSON 解析
  4. 多线程 - GCD、异步编程

# 💡 高级路径(6个月+)

  1. SwiftUI - 声明式 UI 框架
  2. 架构模式 - MVC、MVVM、VIPER
  3. 性能优化 - 内存管理、启动优化
  4. 发布上架 - App Store 发布流程

# 开发环境要求

工具 版本要求 说明
macOS 12.0+ 必须在 Mac 上开发
Xcode 14.0+ 官方 IDE
iOS SDK 15.0+ 支持最新的 iOS 特性
Swift 5.7+ 编程语言版本

# 基础知识

# 开发环境搭建

// Xcode是iOS开发的官方IDE
// 安装Xcode后即可开始iOS开发

// 创建新的iOS项目
// File -> New -> Project -> iOS -> App

// 项目结构
MyApp/
├── MyApp/
│   ├── AppDelegate.swift      // 应用程序代理
│   ├── SceneDelegate.swift    // 场景代理(iOS13├── ViewController.swift   // 视图控制器
│   ├── Main.storyboard        // 主故事板
│   └── Assets.xcassets        // 资源文件
├── MyAppTests/                // 单元测试
└── MyAppUITests/              // UI测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 编程语言基础

# Swift基础语法

// 变量和常量
var variable = "可变变量"        // 可以修改
let constant = "不可变常量"      // 不可修改

// 基本数据类型
let integer: Int = 42
let double: Double = 3.14
let string: String = "Hello, iOS!"
let boolean: Bool = true
let array: [String] = ["iOS", "Swift", "Xcode"]
let dictionary: [String: Any] = ["name": "Jacky", "age": 25]

// 可选类型(Optional)- Swift 的重要特性
var optionalString: String? = "可选字符串"
var nilString: String? = nil
var unwrappedString = optionalString ?? "默认值"  // 空合并运算符

// 可选绑定
if let safeString = optionalString {
    print("安全的值: \(safeString)")
}

// 函数定义
func greet(name: String) -> String {
    return "Hello, \(name)!"
}

// 带默认参数的函数
func greet(name: String, greeting: String = "Hello") -> String {
    return "\(greeting), \(name)!"
}

// 闭包(Closure)- Swift 的函数式编程特性
let closure = { (name: String) -> String in
    return "Hello, \(name)!"
}

// 简化闭包语法
let simpleClosure = { "Hello, World!" }
let addClosure = { (a: Int, b: Int) -> Int in a + b }

// 类和结构体
class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func introduce() -> String {
        return "I'm \(name), \(age) years old."
    }
}

// 结构体(值类型)- 推荐用于数据模型
struct Point {
    var x: Double
    var y: Double
    
    // 计算属性
    var distanceFromOrigin: Double {
        return sqrt(x * x + y * y)
    }
}

// 使用示例
let person = Person(name: "Alice", age: 25)
print(person.introduce())

let point = Point(x: 3.0, y: 4.0)
print("距离原点: \(point.distanceFromOrigin)")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

# Swift 重要特性详解

# 1. 可选类型(Optionals)
// 可选类型是 Swift 的安全特性,避免空指针异常
var name: String? = "Alice"
var age: Int? = nil

// 安全解包
if let unwrappedName = name {
    print("姓名: \(unwrappedName)")
}

// 空合并运算符
let displayName = name ?? "未知用户"

// 强制解包(谨慎使用)
let forceUnwrapped = name! // 如果 name 为 nil 会崩溃
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2. 协议(Protocols)
// 定义协议
protocol Drawable {
    func draw()
    var area: Double { get }
}

// 遵循协议
struct Circle: Drawable {
    let radius: Double
    
    func draw() {
        print("绘制圆形")
    }
    
    var area: Double {
        return Double.pi * radius * radius
    }
}

// 使用协议
func render(_ shape: Drawable) {
    shape.draw()
    print("面积: \(shape.area)")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3. 扩展(Extensions)
// 为现有类型添加功能
extension String {
    func isEmail() -> Bool {
        return self.contains("@") && self.contains(".")
    }
    
    var reversed: String {
        return String(self.reversed())
    }
}

let email = "[email protected]"
print(email.isEmail()) // true
print(email.reversed) // moc.elpmaxe@resu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4. 泛型(Generics)
// 泛型函数
func swap<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

var x = 10
var y = 20
swap(&x, &y)
print("x: \(x), y: \(y)") // x: 20, y: 10

// 泛型结构体
struct Stack<Element> {
    private var items: [Element] = []
    
    mutating func push(_ item: Element) {
        items.append(item)
    }
    
    mutating func pop() -> Element? {
        return items.popLast()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Objective-C基础语法

// 头文件声明 (Person.h)
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;

- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
- (NSString *)introduce;

@end

// 实现文件 (Person.m)
@implementation Person

- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
    self = [super init];
    if (self) {
        _name = name;
        _age = age;
    }
    return self;
}

- (NSString *)introduce {
    return [NSString stringWithFormat:@"I'm %@, %ld years old.", self.name, (long)self.age];
}

@end

// 使用示例
Person *person = [[Person alloc] initWithName:@"Alice" age:25];
NSLog(@"%@", [person introduce]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 核心框架

iOS开发涉及多个核心框架,每个框架负责不同的功能模块。

# UIKit框架

UIKit是iOS应用开发的主要UI框架,提供了丰富的用户界面组件。

# 视图控制器

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        // 设置背景色
        view.backgroundColor = .white
        
        // 创建标签
        let label = UILabel()
        label.text = "Hello, iOS!"
        label.textAlignment = .center
        label.frame = CGRect(x: 50, y: 100, width: 200, height: 50)
        view.addSubview(label)
        
        // 创建按钮
        let button = UIButton(type: .system)
        button.setTitle("点击我", for: .normal)
        button.frame = CGRect(x: 50, y: 200, width: 100, height: 40)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        view.addSubview(button)
    }
    
    @objc private func buttonTapped() {
        print("按钮被点击了!")
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 常用UI组件

// UILabel - 标签
let label = UILabel()
label.text = "显示文本"
label.font = UIFont.systemFont(ofSize: 16)
label.textColor = .black
label.numberOfLines = 0 // 多行显示

// UIButton - 按钮
let button = UIButton(type: .system)
button.setTitle("按钮", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.backgroundColor = .lightGray

// UITextField - 文本输入框
let textField = UITextField()
textField.placeholder = "请输入文本"
textField.borderStyle = .roundedRect
textField.delegate = self

// UIImageView - 图片视图
let imageView = UIImageView()
imageView.image = UIImage(named: "icon")
imageView.contentMode = .scaleAspectFit

// UITableView - 表格视图
let tableView = UITableView()
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

// UICollectionView - 集合视图
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
collectionView.delegate = self
collectionView.dataSource = self
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# SwiftUI框架

SwiftUI是苹果推出的声明式UI框架,使用Swift语言构建用户界面。

# 基本视图

import SwiftUI

struct ContentView: View {
    @State private var text = ""
    @State private var isShowingAlert = false
    
    var body: some View {
        VStack(spacing:20[object Object]            Text("Hello, SwiftUI!)
                .font(.largeTitle)
                .foregroundColor(.blue)
            
            TextField("请输入文本", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Button("点击我")[object Object]                isShowingAlert = true
            }
            .alert(提示", isPresented: $isShowingAlert)[object Object]            Button("确定)[object Object]         } message:[object Object]              Text("你点击了按钮!")
            }
        }
        .padding()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 常用SwiftUI组件

// 文本组件
Text("Hello, SwiftUI!")
    .font(.title)
    .foregroundColor(.blue)
    .padding()

// 按钮组件
Button("点击) [object Object]   print(按钮被点击")
}
.buttonStyle(.borderedProminent)

// 输入框
TextField("请输入", text: $inputText)
    .textFieldStyle(.roundedBorder)

// 图片
Image("icon")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 10, height: 100)

// 列表
List(items) { item in
    HStack {
        Text(item.title)
        Spacer()
        Text(item.description)
    }
}

// 导航
NavigationView {
    List {
        NavigationLink("详情页面", destination: DetailView())
    }
    .navigationTitle("主页面")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 数据存储

iOS提供了多种数据存储方式,适用于不同的使用场景。

# UserDefaults

适用于存储简单的用户偏好设置。

// 存储数据
UserDefaults.standard.set(Jacky forKey: "username")
UserDefaults.standard.set(25orKey: "age")
UserDefaults.standard.set(true, forKey: isLoggedIn")

// 读取数据
let username = UserDefaults.standard.string(forKey: username) ??age = UserDefaults.standard.integer(forKey: "age")
let isLoggedIn = UserDefaults.standard.bool(forKey: isLoggedIn")

// 删除数据
UserDefaults.standard.removeObject(forKey: username")

// 同步到磁盘
UserDefaults.standard.synchronize()
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# Core Data

适用于复杂的数据模型和关系型数据存储。

import CoreData

// 数据模型定义
class Person: NSManagedObject {
    @NSManaged var name: String
    @NSManaged var age: Int16
    @NSManaged var email: String?
}

// Core Data操作
class CoreDataManager {
    static let shared = CoreDataManager()
    
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "DataModel")
        container.loadPersistentStores { _, error in
            if let error = error[object Object]             fatalError(Core Data加载失败: \(error)")
            }
        }
        return container
    }()
    
    var context: NSManagedObjectContext {
        return persistentContainer.viewContext
    }
    
    // 保存数据
    func saveContext() {
        if context.hasChanges {
            do[object Object]               try context.save()
            } catch[object Object]             print(保存失败: (error)")
            }
        }
    }
    
    // 创建新记录
    func createPerson(name: String, age: Int16email: String?) -> Person {
        let person = Person(context: context)
        person.name = name
        person.age = age
        person.email = email
        saveContext()
        return person
    }
    
    // 查询数据
    func fetchPersons() -> [Person] {
        let request: NSFetchRequest<Person> = Person.fetchRequest()
        do {
            return try context.fetch(request)
        } catch {
            print(查询失败: (error)")
            return []
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

# 文件系统

适用于存储大文件或自定义格式的数据。

class FileManager {
    static let shared = FileManager()
    
    // 获取文档目录
    func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths0
    }
    
    // 保存文件
    func saveFile(data: Data, filename: String) -> Bool[object Object]
        let url = getDocumentsDirectory().appendingPathComponent(filename)
        do[object Object]          try data.write(to: url)
            return true
        } catch {
            print("保存文件失败: \(error)")
            return false
        }
    }
    
    // 读取文件
    func readFile(filename: String) -> Data?[object Object]
        let url = getDocumentsDirectory().appendingPathComponent(filename)
        do {
            return try Data(contentsOf: url)
        } catch {
            print("读取文件失败: \(error)")
            return nil
        }
    }
    
    // 删除文件
    func deleteFile(filename: String) -> Bool[object Object]
        let url = getDocumentsDirectory().appendingPathComponent(filename)
        do[object Object]          try FileManager.default.removeItem(at: url)
            return true
        } catch {
            print("删除文件失败: \(error)")
            return false
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 网络通信

iOS提供了多种网络通信方式,支持HTTP/HTTPS、WebSocket等协议。

# URLSession

用于HTTP/HTTPS网络请求。

class NetworkManager {
    static let shared = NetworkManager()
    
    // GET请求
    func getData(from urlString: String, completion: @escaping (Data?, Error?) -> Void) {
        guard let url = URL(string: urlString) else {
            completion(nil, NSError(domain: "Invalid URL", code:-1, userInfo: nil))
            return
        }
        
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            DispatchQueue.main.async[object Object]        completion(data, error)
            }
        }
        task.resume()
    }
    
    // POST请求
    func postData(to urlString: String, data: Data, completion: @escaping (Data?, Error?) -> Void) {
        guard let url = URL(string: urlString) else {
            completion(nil, NSError(domain: "Invalid URL", code:-1, userInfo: nil))
            return
        }
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = data
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            DispatchQueue.main.async[object Object]        completion(data, error)
            }
        }
        task.resume()
    }
    
    // JSON解码
    func decode<T: Codable>(_ type: T.Type, from data: Data) -> T? {
        do {
            return try JSONDecoder().decode(type, from: data)
        } catch {
            print(JSON解码失败: \(error)")
            return nil
        }
    }
}

// 使用示例
struct User: Codable [object Object]   let id: Int
    let name: String
    let email: String
}

NetworkManager.shared.getData(from: "https://api.example.com/users")[object Object]data, error in
    if let data = data {
        let users = NetworkManager.shared.decode([User].self, from: data)
        print(获取到用户: \(users ?? [])")
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# WebSocket

用于实时双向通信。

import Foundation

class WebSocketManager: NSObject[object Object]   private var webSocket: URLSessionWebSocketTask?
    private var session: URLSession!
    
    override init() {
        super.init()
        session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
    }
    
    func connect(to urlString: String) {
        guard let url = URL(string: urlString) else { return }
        webSocket = session.webSocketTask(with: url)
        webSocket?.resume()
        receiveMessage()
    }
    
    func send(_ message: String) {
        let message = URLSessionWebSocketTask.Message.string(message)
        webSocket?.send(message) { error in
            if let error = error[object Object]             print("发送消息失败: \(error)")
            }
        }
    }
    
    private func receiveMessage() {
        webSocket?.receive { [weak self] result in
            switch result [object Object]            case .success(let message):
                switch message[object Object]              case .string(let text):
                    print("收到消息: \(text))              case .data(let data):
                    print("收到数据: \(data))
                @unknown default:
                    break
                }
                self?.receiveMessage() // 继续接收下一条消息
            case .failure(let error):
                print("接收消息失败: \(error)")
            }
        }
    }
    
    func disconnect() {
        webSocket?.cancel(with: .normalClosure, reason: nil)
    }
}

extension WebSocketManager: URLSessionWebSocketDelegate {
    func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?)[object Object]        print(WebSocket连接已建立")
    }
    
    func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?)[object Object]        print(WebSocket连接已关闭)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 多线程和异步编程

iOS提供了多种多线程和异步编程的方式。

# GCD (Grand Central Dispatch)

// 主队列(UI更新)
DispatchQueue.main.async[object Object]  // 更新UI
    self.label.text = 更新完成"
}

// 全局队列(后台任务)
DispatchQueue.global(qos: .background).async {
    // 执行耗时操作
    let result = self.performHeavyTask()
    
    // 完成后回到主队列更新UI
    DispatchQueue.main.async {
        self.updateUI(with: result)
    }
}

// 自定义队列
let customQueue = DispatchQueue(label:com.myapp.custom", qos: .userInitiated)
customQueue.async[object Object]
    // 执行任务
}

// 延迟执行
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) [object Object]   print("2秒后执行")
}

// 并发队列
let concurrentQueue = DispatchQueue(label: "com.myapp.concurrent", attributes: .concurrent)
concurrentQueue.async[object Object]    // 并发任务1
}
concurrentQueue.async [object Object]    // 并发任务2
}

// 同步执行
concurrentQueue.sync {
    // 同步任务
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# Operation和OperationQueue

class DataProcessingOperation: Operation[object Object]  private let data: Data
    var processedResult: String?
    
    init(data: Data) {
        self.data = data
        super.init()
    }
    
    override func main()[object Object]
        guard !isCancelled else { return }
        
        // 处理数据
        processedResult = processData(data)
    }
    
    private func processData(_ data: Data) -> String {
        // 模拟数据处理
        return 处理结果"
    }
}

// 使用OperationQueue
let operationQueue = OperationQueue()
operationQueue.maxConcurrentOperationCount =3

let operation1rocessingOperation(data: Data())
let operation2rocessingOperation(data: Data())

// 设置依赖关系
operation2.addDependency(operation1operationQueue.addOperation(operation1)
operationQueue.addOperation(operation2)

// 监听完成
operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)
operationQueue.completionBlock =[object Object]
    print("所有操作完成")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# async/await (iOS 15+)

// 异步函数
func fetchUserData() async throws -> User {
    let url = URL(string: "https://api.example.com/user)!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

// 并发执行
func fetchMultipleUsers() async throws -> [User] {
    async let user1 = fetchUserData()
    async let user2 = fetchUserData()
    async let user3 = fetchUserData()
    
    return try await [user1, user2ser3]
}

// 使用Task
Task [object Object]  do [object Object]        let user = try await fetchUserData()
        await MainActor.run[object Object]
            // 更新UI
            self.updateUI(with: user)
        }
    } catch[object Object]
        print(获取用户数据失败: \(error))
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 内存管理

iOS使用ARC(Automatic Reference Counting)进行内存管理。

# 引用类型

// 强引用(默认)
class Person {
    var name: String
    var friend: Person? // 强引用
    
    init(name: String) {
        self.name = name
    }
    
    deinit[object Object]
        print((name) 被释放)
    }
}

// 弱引用
class Person {
    var name: String
    weak var friend: Person? // 弱引用,不会增加引用计数
    
    init(name: String) {
        self.name = name
    }
}

// 无主引用
class Person {
    var name: String
    unowned var friend: Person // 无主引用,假设引用对象永远不会为nil
    
    init(name: String, friend: Person) {
        self.name = name
        self.friend = friend
    }
}

// 闭包中的循环引用
class ViewController: UIViewController {
    var completionHandler: (() -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 使用weak self避免循环引用
        completionHandler = { [weak self] in
            self?.doSomething()
        }
        
        // 或者使用unowned self(确保self不会为nil)
        completionHandler = { [unowned self] in
            self.doSomething()
        }
    }
    
    func doSomething()[object Object]
        print("执行操作)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 调试和测试

# 调试技巧

// 断点和日志
func debugExample() [object Object]    let value = 42
    
    // 条件断点
    if value > 40 [object Object]        print("值大于40
    }
    
    // 断言
    assert(value > 0值必须大于0)
    
    // 打印调试信息
    print(调试信息: \(value)")
    
    // 使用LLDB调试器
    // 在Xcode中设置断点,使用po命令查看变量值
    // po value
}

// 性能分析
func performanceTest() {
    let startTime = CFAbsoluteTimeGetCurrent()
    
    // 执行耗时操作
    for _ in 0..<10000 [object Object]       // 一些操作
    }
    
    let endTime = CFAbsoluteTimeGetCurrent()
    let executionTime = endTime - startTime
    print(执行时间: \(executionTime) 秒)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 单元测试

import XCTest
@testable import MyApp

class MyAppTests: XCTestCase {
    
    override func setUpWithError() throws[object Object]
        // 测试前的设置
    }
    
    override func tearDownWithError() throws[object Object]
        // 测试后的清理
    }
    
    func testExample() throws [object Object]   // 基本测试
        let result = 2 + 2
        XCTAssertEqual(result, 4, "22等于 4   }
    
    func testPerformance() throws [object Object]   // 性能测试
        measure[object Object]
            // 测量执行时间的代码
            for _ in 0..<1000[object Object]                // 一些操作
            }
        }
    }
    
    func testAsyncOperation() async throws [object Object]   // 异步测试
        let expectation = XCTestExpectation(description: "异步操作完成")
        
        Task[object Object]
            // 执行异步操作
            let result = await performAsyncOperation()
            XCTAssertNotNil(result)
            expectation.fulfill()
        }
        
        await fulfillment(of: [expectation], timeout: 50)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 应用生命周期

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool[object Object]
        // 应用启动完成
        print("应用启动完成")
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication)[object Object]
        // 应用即将进入非活动状态
        print(应用即将进入非活动状态")
    }
    
    func applicationDidEnterBackground(_ application: UIApplication)[object Object]
        // 应用进入后台
        print("应用进入后台")
    }
    
    func applicationWillEnterForeground(_ application: UIApplication)[object Object]
        // 应用即将进入前台
        print(应用即将进入前台")
    }
    
    func applicationDidBecomeActive(_ application: UIApplication)[object Object]
        // 应用变为活动状态
        print(应用变为活动状态")
    }
    
    func applicationWillTerminate(_ application: UIApplication)[object Object]
        // 应用即将终止
        print(应用即将终止)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 常用第三方库

# CocoaPods

# Podfile
platform :ios, 13.0
target MyApp' do
  use_frameworks!
  
  # 网络请求
  pod Alamofire'
  
  # 图片加载
  podSDWebImage'
  
  # JSON解析
  podSwiftyJSON'
  
  # 自动布局
  podSnapKit'
  
  # 响应式编程
  podRxSwift podRxCocoa  
  # 数据库
  podRealmSwift'
  
  # 测试
  target 'MyAppTests' do
    inherit! :search_paths
    pod Quick'
    pod Nimble'
  end
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# Swift Package Manager

// 在Xcode中添加依赖
// File -> Add Package Dependencies

// 常用包
// https://github.com/Alamofire/Alamofire
// https://github.com/onevcat/Kingfisher
// https://github.com/SwiftyJSON/SwiftyJSON
// https://github.com/SnapKit/SnapKit
1
2
3
4
5
6
7
8

# 实战项目示例

# 简单的待办事项应用

让我们创建一个完整的待办事项应用来巩固所学知识:

import UIKit

// 数据模型
struct TodoItem {
    let id: UUID
    var title: String
    var isCompleted: Bool
    let createdAt: Date
    
    init(title: String) {
        self.id = UUID()
        self.title = title
        self.isCompleted = false
        self.createdAt = Date()
    }
}

// 主视图控制器
class TodoViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var addButton: UIButton!
    
    private var todoItems: [TodoItem] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupTableView()
    }
    
    private func setupUI() {
        title = "待办事项"
        view.backgroundColor = .systemBackground
        
        // 设置文本输入框
        textField.placeholder = "输入新的待办事项"
        textField.borderStyle = .roundedRect
        
        // 设置添加按钮
        addButton.setTitle("添加", for: .normal)
        addButton.backgroundColor = .systemBlue
        addButton.layer.cornerRadius = 8
    }
    
    private func setupTableView() {
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }
    
    @IBAction func addButtonTapped(_ sender: UIButton) {
        guard let text = textField.text, !text.isEmpty else { return }
        
        let newItem = TodoItem(title: text)
        todoItems.append(newItem)
        
        textField.text = ""
        tableView.reloadData()
    }
}

// 表格视图数据源
extension TodoViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return todoItems.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let item = todoItems[indexPath.row]
        
        cell.textLabel?.text = item.title
        cell.accessoryType = item.isCompleted ? .checkmark : .none
        
        return cell
    }
}

// 表格视图代理
extension TodoViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        todoItems[indexPath.row].isCompleted.toggle()
        tableView.reloadRows(at: [indexPath], with: .fade)
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            todoItems.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

# 数据持久化版本

import Foundation

// 数据管理器
class TodoDataManager {
    static let shared = TodoDataManager()
    private let userDefaults = UserDefaults.standard
    private let todoKey = "TodoItems"
    
    private init() {}
    
    func saveTodos(_ todos: [TodoItem]) {
        if let data = try? JSONEncoder().encode(todos) {
            userDefaults.set(data, forKey: todoKey)
        }
    }
    
    func loadTodos() -> [TodoItem] {
        guard let data = userDefaults.data(forKey: todoKey),
              let todos = try? JSONDecoder().decode([TodoItem].self, from: data) else {
            return []
        }
        return todos
    }
}

// 让 TodoItem 遵循 Codable 协议
extension TodoItem: Codable {}

// 在视图控制器中使用
class TodoViewController: UIViewController {
    // ... 其他代码 ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        setupTableView()
        loadTodos()
    }
    
    private func loadTodos() {
        todoItems = TodoDataManager.shared.loadTodos()
        tableView.reloadData()
    }
    
    @IBAction func addButtonTapped(_ sender: UIButton) {
        guard let text = textField.text, !text.isEmpty else { return }
        
        let newItem = TodoItem(title: text)
        todoItems.append(newItem)
        
        // 保存数据
        TodoDataManager.shared.saveTodos(todoItems)
        
        textField.text = ""
        tableView.reloadData()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 最佳实践

# 代码组织

// 使用扩展组织代码
extension ViewController {
    // MARK: - UI相关
    func setupUI() {
        // 设置UI
    }
    
    func updateUI() {
        // 更新UI
    }
}

extension ViewController {
    // MARK: - 网络相关
    func fetchData() {
        // 获取数据
    }
}

extension ViewController {
    // MARK: - 工具方法
    func formatDate(_ date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateStyle = .medium
        return formatter.string(from: date)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 错误处理

enum AppError: Error [object Object] case networkError(String)
    case dataError(String)
    case validationError(String)
}

func handleError(_ error: Error) [object Object]   switch error {
    case AppError.networkError(let message):
        showAlert(title: "网络错误", message: message)
    case AppError.dataError(let message):
        showAlert(title: "数据错误", message: message)
    case AppError.validationError(let message):
        showAlert(title: "验证错误", message: message)
    default:
        showAlert(title: "未知错误", message: error.localizedDescription)
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 性能优化

// 使用懒加载
class ViewController: UIViewController {
    lazy var expensiveView: UIView = [object Object]        let view = UIView()
        // 复杂的初始化代码
        return view
    }()
    
    // 避免在主线程执行耗时操作
    func performHeavyTask() [object Object]     DispatchQueue.global(qos: .background).async[object Object]
            // 耗时操作
            DispatchQueue.main.async[object Object]                // 更新UI
            }
        }
    }
    
    // 使用缓存
    private var imageCache:String: UIImage] = [:]
    
    func loadImage(from url: String, completion: @escaping (UIImage?) -> Void) {
        if let cachedImage = imageCache[url] {
            completion(cachedImage)
            return
        }
        
        // 下载图片并缓存
        // ...
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

这个iOS学习文档涵盖了从基础语法到高级特性的全面内容,包括:

  1. 基础知识 —— 开发环境、编程语言基础
  2. 核心框架 —— UIKit、SwiftUI的使用
  3. 数据存储 —— UserDefaults、Core Data、文件系统
  4. 网络通信 —— URLSession、WebSocket
  5. 多线程与异步 —— GCD、Operation、async/await
  6. 内存管理 —— ARC、引用类型
  7. 调试测试 —— 调试技巧、单元测试
  8. 应用生命周期 —— 各个状态的处理
  9. 第三方库 —— CocoaPods、SPM
  10. 最佳实践 —— 代码组织、错误处理、性能优化

# 常见问题解答

# Q: Swift 和 Objective-C 应该学哪个?

A: 建议从 Swift 开始学习,因为:

  • Swift 是苹果推荐的现代语言
  • 语法更简洁,学习曲线更平缓
  • 新项目大多使用 Swift
  • 可以逐步学习 Objective-C 来维护老项目

# Q: 需要 Mac 才能开发 iOS 应用吗?

A: 是的,iOS 开发必须使用 Mac 系统,因为:

  • Xcode 只能在 macOS 上运行
  • iOS 模拟器需要 macOS 支持
  • 应用签名和发布需要 Mac 环境

# Q: 如何选择 iOS 版本支持?

A: 建议支持 iOS 15.0+,原因:

  • 覆盖 95%+ 的用户设备
  • 可以使用最新的 API 特性
  • 减少兼容性代码

# Q: 学习 iOS 开发需要多长时间?

A: 学习时间因人而异:

  • 基础应用(3-6个月) - 能开发简单的应用
  • 中级开发(6-12个月) - 掌握常用框架和设计模式
  • 高级开发(1-2年) - 能够独立开发复杂应用

# Q: 如何提高 iOS 开发技能?

A: 建议的学习方法:

  1. 多写代码 - 实践是最好的老师
  2. 阅读源码 - 学习优秀的开源项目
  3. 参与社区 - 加入 iOS 开发者社区
  4. 持续学习 - 关注苹果的新技术和更新

# 学习资源推荐

# 📚 官方资源

  • Swift 官方文档 (opens new window)
  • iOS 开发指南 (opens new window)
  • WWDC 视频 (opens new window)

# 🎓 在线课程

  • Stanford CS193p (opens new window) - 斯坦福大学 iOS 开发课程
  • Ray Wenderlich (opens new window) - 高质量的 iOS 教程
  • AppCoda (opens new window) - 适合初学者的教程

# 📱 实战项目

  • iOS 开源项目集合 (opens new window)
  • SwiftUI 示例项目 (opens new window)
  • UIKit 最佳实践 (opens new window)

# 🛠️ 开发工具

  • Xcode (opens new window) - 官方 IDE
  • SwiftUI Previews (opens new window) - 实时预览
  • Instruments (opens new window) - 性能分析工具

# 总结

这个 iOS 学习指南涵盖了从基础到进阶的全面内容,包括:

  1. 基础知识 —— 开发环境、编程语言基础
  2. 核心框架 —— UIKit、SwiftUI 的使用
  3. 数据存储 —— UserDefaults、Core Data、文件系统
  4. 网络通信 —— URLSession、WebSocket
  5. 多线程与异步 —— GCD、Operation、async/await
  6. 内存管理 —— ARC、引用类型
  7. 调试测试 —— 调试技巧、单元测试
  8. 应用生命周期 —— 各个状态的处理
  9. 第三方库 —— CocoaPods、SPM
  10. 最佳实践 —— 代码组织、错误处理、性能优化
  11. 实战项目 —— 完整的待办事项应用示例

通过系统学习这些内容,你将能够:

  • 掌握 iOS 开发的核心概念和技能
  • 独立开发完整的 iOS 应用
  • 理解 iOS 开发的最佳实践
  • 为进阶学习打下坚实基础

记住,iOS 开发是一个持续学习的过程,保持好奇心,多实践,多思考,你一定能成为优秀的 iOS 开发者!

# 链接

  • 官方文档
    • document (opens new window)
    • OC (opens new window)
    • swift (opens new window)
  • appcoda (opens new window) 对初学者而言可能是最好的起点。你可以找到大量不同的教程, 它们都有非常详细的说明。一定要都看下来!
    • docc (opens new window)
  • 经验
    • https://www.runoob.com/w3cnote/10-step-to-become-a-professional-ios-developer.html (opens new window)
  • 项目
    • iOSProject (opens new window)
#iOS
上次更新: 2025/10/09, 20:54:37
iOS横屏播放

iOS横屏播放→

最近更新
01
npx 使用指南
10-12
02
cursor
09-28
03
inspect
07-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式