From ce3889b07d47b15bd1493900014a7fb5ca2a6277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=B4=E9=93=AD?= Date: Wed, 13 Nov 2024 21:39:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E6=8A=80=E6=9C=AF?= =?UTF-8?q?=E6=A0=88=E6=89=8B=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SwiftPamphletApp.xcodeproj/project.pbxproj | 48 ++ .../App/SwiftPamphletAppApp.swift | 19 +- .../Guide/View/GuideListView.swift | 600 +----------------- .../Guide/View/GuideOutline/AppleGuide.swift | 592 +++++++++++++++++ .../Guide/View/GuideOutline/CSGuide.swift | 19 + SwiftPamphletApp/HomeUI/DataLink.swift | 12 +- SwiftPamphletApp/HomeUI/HomeiOSView.swift | 28 +- SwiftPamphletApp/Performance/Perf.swift | 6 + SwiftPamphletApp/Performance/TaskCase.swift | 62 ++ .../TaskCaseViews/TaskCaseAnimationView.swift | 168 +++++ .../TaskCaseViews/TaskCaseBigImageView.swift | 171 +++++ .../TaskCaseViews/TaskCaseCacheView.swift | 117 ++++ .../TaskCaseViews/TaskCasePriorityView.swift | 171 +++++ .../TaskCaseViews/TaskCaseUIUpdateView.swift | 170 +++++ 14 files changed, 1587 insertions(+), 596 deletions(-) create mode 100644 SwiftPamphletApp/Guide/View/GuideOutline/AppleGuide.swift create mode 100644 SwiftPamphletApp/Guide/View/GuideOutline/CSGuide.swift create mode 100644 SwiftPamphletApp/Performance/TaskCase.swift create mode 100644 SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseAnimationView.swift create mode 100644 SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseBigImageView.swift create mode 100644 SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseCacheView.swift create mode 100644 SwiftPamphletApp/Performance/TaskCaseViews/TaskCasePriorityView.swift create mode 100644 SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseUIUpdateView.swift diff --git a/SwiftPamphletApp.xcodeproj/project.pbxproj b/SwiftPamphletApp.xcodeproj/project.pbxproj index 153f550b..d2d41ed1 100644 --- a/SwiftPamphletApp.xcodeproj/project.pbxproj +++ b/SwiftPamphletApp.xcodeproj/project.pbxproj @@ -487,6 +487,14 @@ 3ADBA8512CE216E900B0050B /* Perf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ADBA8502CE216E900B0050B /* Perf.swift */; }; 3AE0D59A2BAB0A0600D6D925 /* DeveloperListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE0D5992BAB0A0600D6D925 /* DeveloperListView.swift */; }; 3AE0D59E2BAB183100D6D925 /* EditDeveloper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE0D59D2BAB183100D6D925 /* EditDeveloper.swift */; }; + 3AE3F94F2CE44B2D007EFDFA /* AppleGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F94E2CE44B2D007EFDFA /* AppleGuide.swift */; }; + 3AE3F9512CE44EF8007EFDFA /* CSGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9502CE44EF8007EFDFA /* CSGuide.swift */; }; + 3AE3F9532CE4532D007EFDFA /* TaskCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9522CE4532D007EFDFA /* TaskCase.swift */; }; + 3AE3F9622CE4A0C5007EFDFA /* TaskCaseUIUpdateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9612CE4A0C5007EFDFA /* TaskCaseUIUpdateView.swift */; }; + 3AE3F9642CE4ADFC007EFDFA /* TaskCaseAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9632CE4ADFC007EFDFA /* TaskCaseAnimationView.swift */; }; + 3AE3F9662CE4BCEA007EFDFA /* TaskCaseBigImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9652CE4BCEA007EFDFA /* TaskCaseBigImageView.swift */; }; + 3AE3F9682CE4C65F007EFDFA /* TaskCaseCacheView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9672CE4C65F007EFDFA /* TaskCaseCacheView.swift */; }; + 3AE3F96A2CE4DC4C007EFDFA /* TaskCasePriorityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE3F9692CE4DC4C007EFDFA /* TaskCasePriorityView.swift */; }; 3AE4CA382BD7813D005BEF2C /* InfoOrganizer in Frameworks */ = {isa = PBXBuildFile; productRef = 3AE4CA372BD7813D005BEF2C /* InfoOrganizer */; }; 3AEC7F4B2CE37028005D510D /* 动态库与静态库(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 3AEC7F4A2CE37028005D510D /* 动态库与静态库(ap).md */; }; 3AEC7F4D2CE373C5005D510D /* 启动优化-测试(ap).md in Resources */ = {isa = PBXBuildFile; fileRef = 3AEC7F4C2CE373C5005D510D /* 启动优化-测试(ap).md */; }; @@ -975,6 +983,14 @@ 3ADBA8502CE216E900B0050B /* Perf.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Perf.swift; sourceTree = ""; }; 3AE0D5992BAB0A0600D6D925 /* DeveloperListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperListView.swift; sourceTree = ""; }; 3AE0D59D2BAB183100D6D925 /* EditDeveloper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditDeveloper.swift; sourceTree = ""; }; + 3AE3F94E2CE44B2D007EFDFA /* AppleGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuide.swift; sourceTree = ""; }; + 3AE3F9502CE44EF8007EFDFA /* CSGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CSGuide.swift; sourceTree = ""; }; + 3AE3F9522CE4532D007EFDFA /* TaskCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCase.swift; sourceTree = ""; }; + 3AE3F9612CE4A0C5007EFDFA /* TaskCaseUIUpdateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCaseUIUpdateView.swift; sourceTree = ""; }; + 3AE3F9632CE4ADFC007EFDFA /* TaskCaseAnimationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCaseAnimationView.swift; sourceTree = ""; }; + 3AE3F9652CE4BCEA007EFDFA /* TaskCaseBigImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCaseBigImageView.swift; sourceTree = ""; }; + 3AE3F9672CE4C65F007EFDFA /* TaskCaseCacheView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCaseCacheView.swift; sourceTree = ""; }; + 3AE3F9692CE4DC4C007EFDFA /* TaskCasePriorityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TaskCasePriorityView.swift; sourceTree = ""; }; 3AEC7F4A2CE37028005D510D /* 动态库与静态库(ap).md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "动态库与静态库(ap).md"; sourceTree = ""; }; 3AEC7F4C2CE373C5005D510D /* 启动优化-测试(ap).md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "启动优化-测试(ap).md"; sourceTree = ""; }; 3AEC7F572CE38749005D510D /* OC项目启动时间(ap).md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "OC项目启动时间(ap).md"; sourceTree = ""; }; @@ -2224,6 +2240,7 @@ 08EF35CE2BECFCD40098E2D4 /* View */ = { isa = PBXGroup; children = ( + 3AE3F94D2CE44B16007EFDFA /* GuideOutline */, 0887A5992BA28F6D00131359 /* CSGuideView.swift */, 08069CAA2BDE01E800D48E24 /* GuideListView.swift */, 08069CAC2BDE7A6B00D48E24 /* GuideDetailView.swift */, @@ -2299,6 +2316,8 @@ 3ADBA8502CE216E900B0050B /* Perf.swift */, 3AA462352CE228CA00774B59 /* NotificationPreheat.swift */, 3AA462372CE261CC00774B59 /* TaskManager.swift */, + 3AE3F9522CE4532D007EFDFA /* TaskCase.swift */, + 3AE3F9602CE49FA2007EFDFA /* TaskCaseViews */, ); path = Performance; sourceTree = ""; @@ -2312,6 +2331,27 @@ path = Developer; sourceTree = ""; }; + 3AE3F94D2CE44B16007EFDFA /* GuideOutline */ = { + isa = PBXGroup; + children = ( + 3AE3F94E2CE44B2D007EFDFA /* AppleGuide.swift */, + 3AE3F9502CE44EF8007EFDFA /* CSGuide.swift */, + ); + path = GuideOutline; + sourceTree = ""; + }; + 3AE3F9602CE49FA2007EFDFA /* TaskCaseViews */ = { + isa = PBXGroup; + children = ( + 3AE3F9612CE4A0C5007EFDFA /* TaskCaseUIUpdateView.swift */, + 3AE3F9632CE4ADFC007EFDFA /* TaskCaseAnimationView.swift */, + 3AE3F9652CE4BCEA007EFDFA /* TaskCaseBigImageView.swift */, + 3AE3F9672CE4C65F007EFDFA /* TaskCaseCacheView.swift */, + 3AE3F9692CE4DC4C007EFDFA /* TaskCasePriorityView.swift */, + ); + path = TaskCaseViews; + sourceTree = ""; + }; 3AEC7F582CE38749005D510D /* 启动时间 */ = { isa = PBXGroup; children = ( @@ -2901,29 +2941,37 @@ 08CD61FE27758B8A008C0935 /* Lexer.swift in Sources */, 08D8F00A2BEFBB2300AA0020 /* WWDCModel.swift in Sources */, 0871C6192BA040E5000B620D /* InfoRowView.swift in Sources */, + 3AE3F9662CE4BCEA007EFDFA /* TaskCaseBigImageView.swift in Sources */, + 3AE3F96A2CE4DC4C007EFDFA /* TaskCasePriorityView.swift in Sources */, + 3AE3F9532CE4532D007EFDFA /* TaskCase.swift in Sources */, 086A5F442744EE2800FECE02 /* SwiftPamphletAppConfig.swift in Sources */, 3AF2A2E12BE22B5800F3BE1B /* UnCategoryInfosView.swift in Sources */, 08A9E1A22BC25D0700A73764 /* ViewComponentMarkdown.swift in Sources */, 0887A59A2BA28F6D00131359 /* CSGuideView.swift in Sources */, 08D8EFE52BED825E00AA0020 /* BookmarkListView.swift in Sources */, 3AF2A2DF2BE22A8C00F3BE1B /* UnCategoryInfoListView.swift in Sources */, + 3AE3F9622CE4A0C5007EFDFA /* TaskCaseUIUpdateView.swift in Sources */, 086A5F362744ED9600FECE02 /* RepoView.swift in Sources */, 084417752B99B9060049297D /* HomeView.swift in Sources */, 3AF2A2E72BE239A300F3BE1B /* ArchivedInfoListView.swift in Sources */, 3ADBA84F2CE209FB00B0050B /* MetricManager.swift in Sources */, 086A5F072744E88E00FECE02 /* SwiftPamphletAppApp.swift in Sources */, 08D8F00E2BF044FB00AA0020 /* WWDCDetailView.swift in Sources */, + 3AE3F94F2CE44B2D007EFDFA /* AppleGuide.swift in Sources */, 08069CAD2BDE7A6B00D48E24 /* GuideDetailView.swift in Sources */, + 3AE3F9682CE4C65F007EFDFA /* TaskCaseCacheView.swift in Sources */, 08AEAEF1277F09D000B969E2 /* IntroView.swift in Sources */, 08397E292B9F0A9100DFDD02 /* EditInfoView.swift in Sources */, 08D8F00C2BEFCFCF00AA0020 /* WWDCListView.swift in Sources */, 08A7FF312BEB02EA00E12E5A /* GithubAccessTokenView.swift in Sources */, + 3AE3F9642CE4ADFC007EFDFA /* TaskCaseAnimationView.swift in Sources */, 086A5F372744ED9600FECE02 /* UserView.swift in Sources */, 086A5F522744EF4C00FECE02 /* ViewComponent.swift in Sources */, 3ADBA8512CE216E900B0050B /* Perf.swift in Sources */, 08CD61FF27758B8A008C0935 /* Token.swift in Sources */, 3AE0D59E2BAB183100D6D925 /* EditDeveloper.swift in Sources */, 08EF35D22BECFDA80098E2D4 /* BookmarkModel.swift in Sources */, + 3AE3F9512CE44EF8007EFDFA /* CSGuide.swift in Sources */, 086A5F462744EEB900FECE02 /* FundationFunction.swift in Sources */, 3AA462382CE261CC00774B59 /* TaskManager.swift in Sources */, 084E1A6527B51EDB0072BBB6 /* AutoTask.swift in Sources */, diff --git a/SwiftPamphletApp/App/SwiftPamphletAppApp.swift b/SwiftPamphletApp/App/SwiftPamphletAppApp.swift index 4f297423..8b005c0f 100644 --- a/SwiftPamphletApp/App/SwiftPamphletAppApp.swift +++ b/SwiftPamphletApp/App/SwiftPamphletAppApp.swift @@ -54,19 +54,24 @@ struct SwiftPamphletAppApp: App { self.handleAppRefresh(task: task as! BGAppRefreshTask) } scheduleAppRefresh() + // 任务示例 +// TaskCase().bad() + TaskCase().good() // 任务管理器示例 - taskgroupDemo() +// taskgroupDemo() #if DEBUG - // 主界面加载完成,记录终点 - let launchEndTime = DispatchTime.now() - let launchTime = Double(launchEndTime.uptimeNanoseconds - launchStartTime.uptimeNanoseconds) / 1_000_000_000 - print("手动打点 Post-main : \(launchTime) 秒") - // 查看整体从进程创建到主界面加载完成时间,只在开发环境下执行 if let processStartTime = Perf.getProcessRunningTime() { - print("进程创建到主界面加载完成时间: \(String(format: "%.2f", processStartTime)) 秒") + // 主界面加载完成,记录终点 + let launchEndTime = DispatchTime.now() + let launchTime = Double(launchEndTime.uptimeNanoseconds - launchStartTime.uptimeNanoseconds) / 1_000_000_000 + + // Pre-main + print("Pre-main : \(String(format: "%.2f", (processStartTime - launchTime))) 秒") + // Post-main + print("进程创建到主界面显示时间: \(String(format: "%.2f", processStartTime)) 秒") } else { print("无法获取进程创建时间") } diff --git a/SwiftPamphletApp/Guide/View/GuideListView.swift b/SwiftPamphletApp/Guide/View/GuideListView.swift index 645e3af9..2c23d084 100644 --- a/SwiftPamphletApp/Guide/View/GuideListView.swift +++ b/SwiftPamphletApp/Guide/View/GuideListView.swift @@ -12,7 +12,7 @@ import SMFile struct GuideListView: View { @Query(BookmarkModel.all) var bookmarks: [BookmarkModel] @State private var apBookmarks: [String] = [String]() - @State private var listModel = GuideListModel() + @State var listModel = GuideListModel() @State private var limit: Int = 50 @State private var trigger = false // 触发列表书签状态更新 var body: some View { @@ -33,7 +33,7 @@ struct GuideListView: View { destination: GuideDetailView( t: i.t, icon: i.icon, - plName: "ap", + plName: listModel.plName, limit: $limit, trigger: $trigger ) @@ -94,9 +94,10 @@ struct GuideListView: View { func updateApBookmarks() { apBookmarks = [String]() for bm in bookmarks { - if bm.pamphletName == "ap" { - apBookmarks.append(bm.name) - } +// if bm.pamphletName == "ap" { +// apBookmarks.append(bm.name) +// } + apBookmarks.append(bm.name) } } } @@ -104,6 +105,13 @@ struct GuideListView: View { @Observable final class GuideListModel { var searchText = "" + var lModel: [L] + var plName: String = "ap" + + init(plModel: [L] = AppleGuide().outline, pplName: String = "ap") { + self.lModel = plModel + self.plName = pplName + } func filtered() -> [L] { guard !searchText.isEmpty else { return lModel } @@ -175,587 +183,7 @@ final class GuideListModel { SMFile.writeToDownload(fileName: "read.md", content: md) } - var lModel = [ - L(t: "Swift语法", icon: "swift", sub: [ - L(t: "语法基础", sub: [ - L(t: "变量"), - L(t: "打印", icon: "printer"), - L(t: "注释", icon: "number.square"), - L(t: "可选", icon: "exclamationmark.questionmark"), - L(t: "闭包"), - L(t: "函数"), - L(t: "访问控制"), - L(t: "Regex") - ]), - L(t: "基础类型", sub: [ - L(t: "数字"), - L(t: "布尔数"), - L(t: "字符串"), - L(t: "枚举"), - L(t: "元组"), - L(t: "泛型和协议"), - L(t: "不透明类型"), - L(t: "Result"), - L(t: "类型转换") - ]), - L(t: "类和结构体",sub: [ - L(t: "类"), - L(t: "结构体"), - L(t: "属性"), - L(t: "方法"), - L(t: "继承") - ]), - L(t: "函数式",sub: [ - L(t: "map"), - L(t: "filter"), - L(t: "reduce"), - L(t: "sorted") - ]), - L(t: "控制流",sub: [ - L(t: "If"), - L(t: "Guard"), - L(t: "遍历"), - L(t: "While"), - L(t: "Switch") - ]), - L(t: "集合",sub: [ - L(t: "数组"), - L(t: "Sets"), - L(t: "字典") - ]), - L(t: "操作符",sub: [ - L(t: "赋值"), - L(t: "计算符"), - L(t: "比较运算符"), - L(t: "三元"), - L(t: "Nil-coalescing"), - L(t: "范围"), - L(t: "逻辑"), - L(t: "恒等"), - L(t: "运算符") - ]), - L(t: "Swift各版本演进"), - L(t: "Swift规范"), - L(t: "Swift书单") - ]), - L(t: "基础库", icon: "globe.asia.australia.fill", sub: [ - L(t: "系统及设备", sub: [ - L(t: "系统判断"), - L(t: "版本兼容"), - L(t: "canImport判断库是否可使用"), - L(t: "targetEnvironment环境的判断") - ]), - L(t: "自带属性包装", sub: [ - L(t: "@resultBuilder"), - L(t: "@dynamicMemberLookup动态成员查询"), - L(t: "@dynamicCallable动态可调用类型") - ]), - L(t: "自带协议", sub: [ - L(t: "@resultBuilder"), - L(t: "JSON没有id字段") - ]), - L(t: "格式化", sub: [ - L(t: "格式化"), - L(t: "格式化-数据"), - L(t: "格式化-度量值"), - L(t: "格式化-生活日常"), - ]), - L(t: "时间", icon: "calendar.badge.clock", sub: [ - L(t: "时间"), - L(t: "日期组件"), - L(t: "TimeInterval"), - L(t: "时间-formatted"), - L(t: "时区"), - L(t: "农历公历互转"), - L(t: "字符串时间"), - L(t: "Calendar"), - L(t: "时间-开源库"), - ]), - L(t: "度量值"), - L(t: "Data"), - L(t: "文件"), - L(t: "Scanner"), - L(t: "AttributeString"), - L(t: "随机"), - L(t: "UserDefaults") - ]), - L(t: "SwiftUI",icon: "heart.text.square.fill",sub: [ - L(t: "介绍",sub: [ - L(t: "SwiftUI是什么"), - L(t: "SwiftUI-入门"), - L(t: "SwiftUI参考资料"), - L(t: "SwiftUI对标的UIKit视图"), - ]), - L(t: "图文组件",sub: [ - L(t: "Text", sub: [ - L(t: "Text"), - L(t: "Text-动态时间") - ]), - L(t: "Link"), - L(t: "Label"), - L(t: "TextEditor", icon: "arrow.up.and.down.text.horizontal"), - L(t: "TextField"), - L(t: "Image"), - ]), - L(t: "数据集合组件",icon: "list.bullet.rectangle.fill", sub: [ - L(t: "ForEach"), - L(t: "Scroll视图", icon: "scroll.fill", sub: [ - L(t: "ScrollView", icon: "arrow.up.arrow.down.circle"), - L(t: "固定到滚动视图的顶部",icon: "pin.circle"), - L(t: "滚动到特定的位置"), - L(t: "scrollTargetBehavior分页滚动", icon: "book.pages"), - L(t: "scrollTransition视觉效果"), - L(t: "ScrollView-参考资料", icon: "books.vertical"), - ]), - L(t: "List列表", icon: "list.bullet.rectangle.portrait.fill", sub: [ - L(t: "List", icon: "list.bullet.rectangle.portrait"), - L(t: "List-设置样式"), - L(t: "List-移动元素"), - L(t: "List-搜索", icon: "text.magnifyingglass"), - L(t: "List-下拉刷新", icon: "arrow.circlepath"), - L(t: "List-轻扫操作", icon: "hand.point.up.left.and.text"), - L(t: "List-大纲视图", icon: "list.number"), - L(t: "List-完全可点击的行", icon: "chevron.right.circle"), - L(t: "List-索引标题", icon: "textformat.abc.dottedunderline"), - L(t: "List-加载更多", icon: "arrow.down.circle"), - ]), - L(t: "Lazy容器", sub: [ - L(t: "LazyVStack和LazyHStack"), - L(t: "LazyVGrid和LazyHGrid"), - ]), - L(t: "Grid", icon: "square.grid.3x2"), - L(t: "Table表格", icon: "tablecells.fill", sub: [ - L(t: "Table", icon: "tablecells"), - L(t: "Table-样式", icon: "paintbrush"), - L(t: "Table-行的选择", icon: "line.3.horizontal"), - L(t: "Table-多属性排序", icon: "tablecells.badge.ellipsis"), - L(t: "Table-contextMenu", icon: "filemenu.and.selection"), - L(t: "Table-拖拽"), - L(t: "Table-可交互"), - ]), - ]), - L(t: "布局组件",icon: "rectangle.3.group.fill", sub: [ - L(t: "Navigation导航", icon: "sidebar.squares.leading", sub: [ - L(t: "Navigation", icon: "sidebar.squares.leading"), - L(t: "NavigationStack", icon: "square.stack.3d.down.forward"), - L(t: "NavigationPath", icon: "arrow.3.trianglepath"), - L(t: "NavigationSplitView", icon: "rectangle.split.3x1"), - L(t: "自定义导航栏"), - L(t: "Inspectors右侧多出一栏", icon: "rectangle.split.3x1"), - L(t: "导航状态保存和还原"), - ]), - L(t: "布局基础",icon: "rectangle.3.group", sub: [ - L(t: "布局-基础"), - L(t: "布局-留白", icon: "space"), - L(t: "布局-对齐", icon: "align.vertical.top"), - L(t: "布局-居中", icon: "align.horizontal.center"), - L(t: "布局-offset偏移"), - L(t: "Safe Area"), - L(t: "布局原理"), - ]), - L(t: "布局进阶", sub: [ - L(t: "AnyLayout"), - L(t: "ViewThatFits"), - L(t: "Layout协议"), - L(t: "GeometryReader"), - L(t: "alignmentGuide"), - L(t: "布局进阶-参考资料"), - ]), - L(t: "Stack", icon: "square.3.layers.3d"), - L(t: "GroupBox", icon: "shippingbox"), - L(t: "TabView"), - L(t: "ControlGroup"), - L(t: "Advanced layout control"), - L(t: "ContentUnavailableView"), - ]), - L(t: "表单", sub: [ - L(t: "Form"), - L(t: "Picker选择器", sub: [ - L(t: "Picker", icon: "filemenu.and.selection"), - L(t: "文字Picker", icon: "contextualmenu.and.cursorarrow"), - L(t: "ColorPicker", icon: "paintpalette"), - L(t: "DatePicker", icon: "calendar"), - L(t: "PhotoPicker", icon: "photo.on.rectangle.angled"), - L(t: "字体Picker", icon: "doc.richtext"), - L(t: "WheelPicker"), - ]), - L(t: "Toggle", icon: "togglepower"), - L(t: "Slider", icon: "slider.horizontal.below.sun.max"), - L(t: "Stepper"), - ]), - L(t: "浮层组件", sub: [ - L(t: "浮层"), - L(t: "Sheet"), - L(t: "Full Screen Modal View"), - L(t: "confirmationDialog()"), - L(t: "Alert", icon: "exclamationmark.triangle"), - L(t: "Popover", icon: "text.bubble"), - L(t: "Menu和ContextMenu", icon: "filemenu.and.selection"), - L(t: "HUD", icon: "speedometer"), - ]), - L(t: "视图组件",sub: [ - L(t: "Button"), - L(t: "进度"), - L(t: "Keyboard"), - L(t: "Transferable"), - L(t: "ShareLink") - ]), - L(t: "视觉",sub: [ - L(t: "SwiftUI颜色", icon: "paintbrush"), - L(t: "SwiftUI-Shadow", icon: "moon.circle"), - L(t: "Blend Modes"), - L(t: "SwiftUI-渐变"), - L(t: "SwiftUI-模糊"), - L(t: "SwiftUI-背景材质"), - L(t: "SwiftUI Effect", icon: "sparkles"), - L(t: "SwiftUI Canvas"), - L(t: "SF Symbol", icon: "star"), - L(t: "SwiftCharts", icon: "chart.line.uptrend.xyaxis"), - L(t: "Shaders Metal", icon: "cpu"), - ]), - L(t: "修饰符", sub: [ - L(t: "自定义修饰符"), - L(t: "背景修饰符"), - L(t: "修饰符-visualEffect"), - L(t: "修饰符-圆角"), - L(t: "ContainerRelativeShape"), - L(t: "修饰符-fixedSize"), - L(t: "修饰符-蒙版"), - L(t: "redacted隐私展示"), - ]), - L(t: "视图协议",sub: [ - L(t: "视图协议-简介"), - L(t: "视图协议-核心协议"), - L(t: "Style协议"), - L(t: "小组件协议"), - L(t: "Shapes协议"), - L(t: "Animations协议"), - L(t: "视图协议-Environment"), - L(t: "Previews协议"), - L(t: "Legacy bridges协议"), - L(t: "Responder chain协议"), - L(t: "Toolbar协议"), - L(t: "Documents协议"), - L(t: "特定情况视图协议"), - ]), - L(t: "SwiftUI-自定义样式"), - L(t: "ViewBuilder"), - L(t: "数据流", sub: [ - L(t: "SwiftUI数据流"), - L(t: "SwiftUI数据流-@State"), - L(t: "SwiftUI数据流-@Binding"), - L(t: "SwiftUI数据流-@Observable"), - L(t: "SwiftUI数据流-@Environment"), - L(t: "SwiftUI数据流-@AppStorage") - ]) - ]), - L(t: "SwiftData", icon: "swiftdata", sub: [ - L(t: "SwiftData基础"), - L(t: "创建@Model模型", icon: "plus.rectangle.on.rectangle"), - L(t: "SwiftData-模型关系", icon: "arrow.triangle.2.circlepath"), - L(t: "容器配置modelContainer", icon: "gearshape.2"), - L(t: "增删modelContext"), - L(t: "SwiftData-检索", icon: "magnifyingglass.circle"), - L(t: "SwiftData-处理大量数据", icon: "externaldrive.connected.to.line.below"), - L(t: "SwiftData多线程", icon: "arrow.triangle.branch"), - L(t: "SwiftData-版本迁移", icon: "arrow.right.arrow.left.square"), - L(t: "SwiftData-调试", icon: "ant"), - L(t: "SwiftData和CoreData"), - L(t: "SwiftData-资料", icon: "books.vertical") - ]), - L(t: "小组件", icon: "window.shade.open", sub: [ - L(t: "小组件-StaticConfiguration",icon: "doc.plaintext"), - L(t: "小组件-AppIntentConfiguration"), - L(t: "小组件-配置选项",icon: "rectangle.portrait.bottomleft.inset.filled"), - L(t: "AppIntentTimelineProvider"), - L(t: "Widget View", icon: "rectangle.grid.1x2"), - L(t: "刷新小组件", icon: "arrow.clockwise.circle"), - L(t: "小组件动画", icon: "figure.disc.sports"), - L(t: "小组件-远程定时获取数据", icon: "cloud"), - L(t: "小组件-获取位置权限更新内容", icon: "location.fill.viewfinder"), - L(t: "支持多个小组件", icon: "rectangle.grid.2x2"), - L(t: "获取小组件形状", icon: "rectangle.inset.filled"), - L(t: "小组件-Deep link", icon: "link.circle"), - L(t: "小组件访问SwiftData", icon: "externaldrive"), - L(t: "小组件-参考资料", icon: "books.vertical"), - ]), - L(t: "系统能力",icon: "apple.terminal",sub: [ - L(t: "WeatherKit", icon: "app"), - L(t: "Swift-DocC", icon: "doc.append"), - L(t: "AppIcon", icon: "app"), - L(t: "Share Extension", icon: "app"), - L(t: "Background Fetch", icon: "app") - ]), - L(t: "多线程", icon: "text.line.first.and.arrowtriangle.forward", sub: [ - L(t: "Swift Concurrency",sub: [ - L(t: "Swift Concurrency是什么"), - L(t: "async await"), - L(t: "Async Sequences"), - L(t: "结构化并发"), - L(t: "Actors"), - L(t: "Distributed Actors"), - L(t: "Swift Concurrency相关提案"), - L(t: "Swift Concurrency学习路径"), - L(t: "Swift Concurrency和Combine"), - L(t: "Concurrency技术演进") - ]), - L(t: "Combine",sub: [ - L(t: "介绍",sub: [ - L(t: "Combine是什么"), - L(t: "Combine的资料") - ]), - L(t: "使用说明",sub: [ - L(t: "publisher"), - L(t: "Just"), - L(t: "PassthroughSubject"), - L(t: "Empty"), - L(t: "CurrentValueSubject"), - L(t: "removeDuplicates"), - L(t: "flatMap"), - L(t: "append"), - L(t: "prepend"), - L(t: "merge"), - L(t: "zip"), - L(t: "combineLatest"), - L(t: "Scheduler") - ]), - L(t: "使用场景",sub: [ - L(t: "Combine网络请求"), - L(t: "Combine KVO"), - L(t: "Combine通知"), - L(t: "Combine Timer") - ]) - ]), - ]), - L(t: "图片处理", icon: "photo.stack", sub: [ - L(t: "图片处理-基础") - ]), - L(t: "动画", icon: "moonphase.waning.gibbous.inverse", sub: [ - L(t: "SwiftUI动画", icon: "play"), - L(t: "contentTransition", icon: "number.circle"), - L(t: "animation修饰符", icon: "waveform.path.ecg"), - L(t: "Transaction", icon: "arrow.right.arrow.left"), - L(t: "Matched Geometry Effect", icon: "arrow.triangle.2.circlepath"), - L(t: "PhaseAnimator", icon: "arrow.up.right.circle"), - L(t: "KeyframeAnimator"), - L(t: "布局动画", icon: "squareshape.split.2x2.dotted"), - L(t: "动画-例子", icon: "lightbulb") - ]), - L(t: "网络", icon:"point.3.connected.trianglepath.dotted", sub: [ - L(t: "截获网络请求数据"), - L(t: "网络状态检查"), - L(t: "WKWebView") - ]), - L(t: "性能优化",icon: "battery.100percent.bolt", sub: [ - L(t: "卡顿监控", sub: [ - L(t: "避免视图绘制掉帧"), - L(t: "卡顿原因"), - L(t: "防止卡顿的方法"), - L(t: "RunLoop"), - L(t: "卡死崩溃监控"), - ]), - L(t: "内存管理", sub: [ - L(t: "内存管理"), - L(t: "自动引用计数(ARC)机制"), - L(t: "iOS虚拟内存"), - L(t: "Swift内存安全性及其实现机制"), - L(t: "Swift内存操作"), - L(t: "内存分配器libMalloc"), - L(t: "检测和诊断内存问题"), - ]), - L(t: "崩溃", sub: [ - L(t: "崩溃日志"), - ]), - L(t: "IO性能", sub: [ - L(t: "IO性能-文件系统"), - L(t: "IO性能-文件读写"), - L(t: "IO性能-文件缓存"), - L(t: "文件内存映射(mmap)"), - ]), - L(t: "CPU", sub: [ - L(t: "CPU占用率"), - L(t: "CPU核数和类型"), - ]), - L(t: "启动优化", sub: [ - L(t: "启动时间",sub: [ - L(t: "OC项目启动时间"), - L(t: "Swift项目启动时间"), - ]), - L(t: "启动治理思路"), - L(t: "启动优化-工具"), - L(t: "动态库与静态库"), - L(t: "可合并库"), - L(t: "启动优化-线程任务管理"), - L(t: "启动优化-一些技巧"), - L(t: "启动优化-测试"), - ]), - L(t: "包体积", sub: [ - L(t: "包体积的影响"), - L(t: "包体积-系统优化"), - L(t: "包的分析"), - L(t: "包体积-资源优化"), - L(t: "包体积-代码优化"), - L(t: "Swift无用代码"), - L(t: "包体积-编译优化"), - L(t: "包体积-链接器优化"), - L(t: "包体积-三方库优化"), - ]), - L(t: "性能分析", sub: [ - L(t: "性能分析-工具"), - L(t: "Instruments"), - L(t: "MetricKit"), - L(t: "InApp分析工具"), - L(t: "fishhook"), - L(t: "Frida"), - ]), - L(t: "静态分析", sub: [ - L(t: "静态分析-概述"), - L(t: "静态分析-Swift语言"), - L(t: "SourceKitten"), - L(t: "SwiftSyntax"), - L(t: "Clang静态分析器"), - L(t: "静态分析-代码规范"), - L(t: "Language Server Protocol"), - L(t: "MachO"), - ]), - L(t: "动态性", sub: [ - L(t: "OC运行时"), - L(t: "Swift运行时"), - L(t: "动态库注入技术"), - ]), - L(t: "性能技术演进"), - L(t: "链接器"), - ]), - L(t: "调试", icon: "ant.circle.fill", sub: [ - L(t: "调试"), - L(t: "LLDB"), - ]), - L(t: "测试", icon: "testtube.2", sub: [ - L(t: "自动化测试"), - L(t: "XCTest"), - L(t: "测试-代码覆盖率") - ]), - L(t: "安全", icon: "cross.case", sub: [ - L(t: "安全-介绍"), - L(t: "Keychain") - ]), - L(t: "工程架构与构建",icon: "building.columns.fill", sub: [ - L(t: "架构技术演进"), - L(t: "设计模式"), - L(t: "包管理工具",sub: [ - L(t: "包管理工具-介绍"), - L(t: "Swift Package Manager"), - L(t: "CocoaPods") - ]), - L(t: "组件化模块化"), - L(t: "容器化插件化"), - L(t: "跨平台", sub: [ - L(t: "跨平台-Swift"), - L(t: "跨平台-布局渲染"), - L(t: "跨平台-大厂自研"), - L(t: "跨平台-React Native"), - ]), - L(t: "编辑器", sub: [ - L(t: "Xcode"), - L(t: "编辑器-三方工具"), - L(t: "VSCode"), - ]), - L(t: "Bazel", sub: [ - L(t: "Bazel-介绍"), - L(t: "Bazel-生成Xcode工程"), - L(t: "Bazel-依赖分析"), - L(t: "Bazel-query指令找依赖关系"), - L(t: "Bazel-远程执行配置"), - L(t: "Bazel-远程缓存配置"), - L(t: "Bazel-自定义的构建规则"), - ]), - L(t: "自动化构建流程"), - L(t: "单例"), - L(t: "程序入口点", icon: "door.right.hand.open"), - ]), - L(t: "macOS", icon: "macstudio", sub: [ -// L(t: "macOS技术演进"), - L(t: "macOS范例"), - L(t: "三栏结构"), - L(t: "全屏模式"), - L(t: "macOS共享菜单"), - L(t: "macOS剪贴板") - ]), -// L(t: "visionOS", icon: "visionpro", sub: [ -// L(t: "visionOS-介绍"), -// L(t: "visionOS-入门"), -// L(t: "visionOS-空间设计"), -// L(t: "空间计算和SwiftUI"), -// L(t: "RealityKit"), -// L(t: "Reality Composer Pro"), -// L(t: "visionOS-Model3D"), -// L(t: "visionOS-Object Capture"), -// L(t: "ARKit"), -// L(t: "Metal"), -// L(t: "visionOS-Unity"), -// L(t: "visionOS-系统能力"), -// L(t: "visionOS-空间视频"), -// L(t: "visionOS-声音"), -// ]), -// L(t: "人工智能", icon:"cpu.fill", sub: [ -// L(t: "人工智能-介绍"), -// L(t: "Apple Intelligence"), -// L(t: "Core ML"), -// L(t: "人工智能-模型训练"), -// L(t: "Create ML"), -// L(t: "人工智能-MLX"), -// L(t: "人工智能-文本"), -// L(t: "人工智能-Translation"), -// L(t: "人工智能-Writing Tools"), -// L(t: "人工智能-语音"), -// L(t: "人工智能-视觉"), -// L(t: "人工智能-Metal"), -// L(t: "使用LLM模型"), -// L(t: "使用三方大模型接口"), -// L(t: "Stable Diffusion"), -// L(t: "AI辅助开发APP"), -// L(t: "用于开发APP的提示词"), -// L(t: "人工智能-RAG"), -// L(t: "人工智能-技术原理"), -// ]), - L(t: "三方库使用", icon:"tray.2", sub: [ - L(t: "SQLite.swift的使用") - ]), -// L(t: "开源", icon:"globe.asia.australia", sub: [ -// L(t: "开源-精品项目"), -// L(t: "开源-有趣的项目"), -// L(t: "开源-天气"), -// L(t: "开源-时间"), -// L(t: "开源-学习"), -// L(t: "开源-生活"), -// L(t: "开源-理财"), -// L(t: "开源-阅读"), -// L(t: "开源-笔记"), -// L(t: "开源-音乐"), -// L(t: "开源-动画"), -// L(t: "macOS开源", sub: [ -// L(t: "macOS开源-窗口管理"), -// L(t: "macOS开源-系统监控"), -// L(t: "macOS开源-系统清理"), -// ]), -// ]), - L(t: "知识管理", icon:"lightbulb.max", sub: [ - L(t: "知识管理-介绍"), - L(t: "怎么用小册子APP做知识管理"), - L(t: "知识管理-PKM"), - L(t: "知识管理-工具"), - L(t: "知识管理-输入"), - L(t: "笔记记录方法"), - L(t: "卡片盒笔记法"), - L(t: "PARA记录法"), - L(t: "费曼学习法"), - L(t: "知识管理-CODE方法论"), - L(t: "知识管理-网状和树状"), - L(t: "知识管理-消化"), - L(t: "知识管理-输出"), - L(t: "知识管理-目的导向工作流"), - ]) - ] + } diff --git a/SwiftPamphletApp/Guide/View/GuideOutline/AppleGuide.swift b/SwiftPamphletApp/Guide/View/GuideOutline/AppleGuide.swift new file mode 100644 index 00000000..14657fdb --- /dev/null +++ b/SwiftPamphletApp/Guide/View/GuideOutline/AppleGuide.swift @@ -0,0 +1,592 @@ +// +// AppleGuide.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import Foundation + +struct AppleGuide { + var outline = [ + L(t: "Swift语法", icon: "swift", sub: [ + L(t: "语法基础", sub: [ + L(t: "变量"), + L(t: "打印", icon: "printer"), + L(t: "注释", icon: "number.square"), + L(t: "可选", icon: "exclamationmark.questionmark"), + L(t: "闭包"), + L(t: "函数"), + L(t: "访问控制"), + L(t: "Regex") + ]), + L(t: "基础类型", sub: [ + L(t: "数字"), + L(t: "布尔数"), + L(t: "字符串"), + L(t: "枚举"), + L(t: "元组"), + L(t: "泛型和协议"), + L(t: "不透明类型"), + L(t: "Result"), + L(t: "类型转换") + ]), + L(t: "类和结构体",sub: [ + L(t: "类"), + L(t: "结构体"), + L(t: "属性"), + L(t: "方法"), + L(t: "继承") + ]), + L(t: "函数式",sub: [ + L(t: "map"), + L(t: "filter"), + L(t: "reduce"), + L(t: "sorted") + ]), + L(t: "控制流",sub: [ + L(t: "If"), + L(t: "Guard"), + L(t: "遍历"), + L(t: "While"), + L(t: "Switch") + ]), + L(t: "集合",sub: [ + L(t: "数组"), + L(t: "Sets"), + L(t: "字典") + ]), + L(t: "操作符",sub: [ + L(t: "赋值"), + L(t: "计算符"), + L(t: "比较运算符"), + L(t: "三元"), + L(t: "Nil-coalescing"), + L(t: "范围"), + L(t: "逻辑"), + L(t: "恒等"), + L(t: "运算符") + ]), + L(t: "Swift各版本演进"), + L(t: "Swift规范"), + L(t: "Swift书单") + ]), + L(t: "基础库", icon: "globe.asia.australia.fill", sub: [ + L(t: "系统及设备", sub: [ + L(t: "系统判断"), + L(t: "版本兼容"), + L(t: "canImport判断库是否可使用"), + L(t: "targetEnvironment环境的判断") + ]), + L(t: "自带属性包装", sub: [ + L(t: "@resultBuilder"), + L(t: "@dynamicMemberLookup动态成员查询"), + L(t: "@dynamicCallable动态可调用类型") + ]), + L(t: "自带协议", sub: [ + L(t: "@resultBuilder"), + L(t: "JSON没有id字段") + ]), + L(t: "格式化", sub: [ + L(t: "格式化"), + L(t: "格式化-数据"), + L(t: "格式化-度量值"), + L(t: "格式化-生活日常"), + ]), + L(t: "时间", icon: "calendar.badge.clock", sub: [ + L(t: "时间"), + L(t: "日期组件"), + L(t: "TimeInterval"), + L(t: "时间-formatted"), + L(t: "时区"), + L(t: "农历公历互转"), + L(t: "字符串时间"), + L(t: "Calendar"), + L(t: "时间-开源库"), + ]), + L(t: "度量值"), + L(t: "Data"), + L(t: "文件"), + L(t: "Scanner"), + L(t: "AttributeString"), + L(t: "随机"), + L(t: "UserDefaults") + ]), + L(t: "SwiftUI",icon: "heart.text.square.fill",sub: [ + L(t: "介绍",sub: [ + L(t: "SwiftUI是什么"), + L(t: "SwiftUI-入门"), + L(t: "SwiftUI参考资料"), + L(t: "SwiftUI对标的UIKit视图"), + ]), + L(t: "图文组件",sub: [ + L(t: "Text", sub: [ + L(t: "Text"), + L(t: "Text-动态时间") + ]), + L(t: "Link"), + L(t: "Label"), + L(t: "TextEditor", icon: "arrow.up.and.down.text.horizontal"), + L(t: "TextField"), + L(t: "Image"), + ]), + L(t: "数据集合组件",icon: "list.bullet.rectangle.fill", sub: [ + L(t: "ForEach"), + L(t: "Scroll视图", icon: "scroll.fill", sub: [ + L(t: "ScrollView", icon: "arrow.up.arrow.down.circle"), + L(t: "固定到滚动视图的顶部",icon: "pin.circle"), + L(t: "滚动到特定的位置"), + L(t: "scrollTargetBehavior分页滚动", icon: "book.pages"), + L(t: "scrollTransition视觉效果"), + L(t: "ScrollView-参考资料", icon: "books.vertical"), + ]), + L(t: "List列表", icon: "list.bullet.rectangle.portrait.fill", sub: [ + L(t: "List", icon: "list.bullet.rectangle.portrait"), + L(t: "List-设置样式"), + L(t: "List-移动元素"), + L(t: "List-搜索", icon: "text.magnifyingglass"), + L(t: "List-下拉刷新", icon: "arrow.circlepath"), + L(t: "List-轻扫操作", icon: "hand.point.up.left.and.text"), + L(t: "List-大纲视图", icon: "list.number"), + L(t: "List-完全可点击的行", icon: "chevron.right.circle"), + L(t: "List-索引标题", icon: "textformat.abc.dottedunderline"), + L(t: "List-加载更多", icon: "arrow.down.circle"), + ]), + L(t: "Lazy容器", sub: [ + L(t: "LazyVStack和LazyHStack"), + L(t: "LazyVGrid和LazyHGrid"), + ]), + L(t: "Grid", icon: "square.grid.3x2"), + L(t: "Table表格", icon: "tablecells.fill", sub: [ + L(t: "Table", icon: "tablecells"), + L(t: "Table-样式", icon: "paintbrush"), + L(t: "Table-行的选择", icon: "line.3.horizontal"), + L(t: "Table-多属性排序", icon: "tablecells.badge.ellipsis"), + L(t: "Table-contextMenu", icon: "filemenu.and.selection"), + L(t: "Table-拖拽"), + L(t: "Table-可交互"), + ]), + ]), + L(t: "布局组件",icon: "rectangle.3.group.fill", sub: [ + L(t: "Navigation导航", icon: "sidebar.squares.leading", sub: [ + L(t: "Navigation", icon: "sidebar.squares.leading"), + L(t: "NavigationStack", icon: "square.stack.3d.down.forward"), + L(t: "NavigationPath", icon: "arrow.3.trianglepath"), + L(t: "NavigationSplitView", icon: "rectangle.split.3x1"), + L(t: "自定义导航栏"), + L(t: "Inspectors右侧多出一栏", icon: "rectangle.split.3x1"), + L(t: "导航状态保存和还原"), + ]), + L(t: "布局基础",icon: "rectangle.3.group", sub: [ + L(t: "布局-基础"), + L(t: "布局-留白", icon: "space"), + L(t: "布局-对齐", icon: "align.vertical.top"), + L(t: "布局-居中", icon: "align.horizontal.center"), + L(t: "布局-offset偏移"), + L(t: "Safe Area"), + L(t: "布局原理"), + ]), + L(t: "布局进阶", sub: [ + L(t: "AnyLayout"), + L(t: "ViewThatFits"), + L(t: "Layout协议"), + L(t: "GeometryReader"), + L(t: "alignmentGuide"), + L(t: "布局进阶-参考资料"), + ]), + L(t: "Stack", icon: "square.3.layers.3d"), + L(t: "GroupBox", icon: "shippingbox"), + L(t: "TabView"), + L(t: "ControlGroup"), + L(t: "Advanced layout control"), + L(t: "ContentUnavailableView"), + ]), + L(t: "表单", sub: [ + L(t: "Form"), + L(t: "Picker选择器", sub: [ + L(t: "Picker", icon: "filemenu.and.selection"), + L(t: "文字Picker", icon: "contextualmenu.and.cursorarrow"), + L(t: "ColorPicker", icon: "paintpalette"), + L(t: "DatePicker", icon: "calendar"), + L(t: "PhotoPicker", icon: "photo.on.rectangle.angled"), + L(t: "字体Picker", icon: "doc.richtext"), + L(t: "WheelPicker"), + ]), + L(t: "Toggle", icon: "togglepower"), + L(t: "Slider", icon: "slider.horizontal.below.sun.max"), + L(t: "Stepper"), + ]), + L(t: "浮层组件", sub: [ + L(t: "浮层"), + L(t: "Sheet"), + L(t: "Full Screen Modal View"), + L(t: "confirmationDialog()"), + L(t: "Alert", icon: "exclamationmark.triangle"), + L(t: "Popover", icon: "text.bubble"), + L(t: "Menu和ContextMenu", icon: "filemenu.and.selection"), + L(t: "HUD", icon: "speedometer"), + ]), + L(t: "视图组件",sub: [ + L(t: "Button"), + L(t: "进度"), + L(t: "Keyboard"), + L(t: "Transferable"), + L(t: "ShareLink") + ]), + L(t: "视觉",sub: [ + L(t: "SwiftUI颜色", icon: "paintbrush"), + L(t: "SwiftUI-Shadow", icon: "moon.circle"), + L(t: "Blend Modes"), + L(t: "SwiftUI-渐变"), + L(t: "SwiftUI-模糊"), + L(t: "SwiftUI-背景材质"), + L(t: "SwiftUI Effect", icon: "sparkles"), + L(t: "SwiftUI Canvas"), + L(t: "SF Symbol", icon: "star"), + L(t: "SwiftCharts", icon: "chart.line.uptrend.xyaxis"), + L(t: "Shaders Metal", icon: "cpu"), + ]), + L(t: "修饰符", sub: [ + L(t: "自定义修饰符"), + L(t: "背景修饰符"), + L(t: "修饰符-visualEffect"), + L(t: "修饰符-圆角"), + L(t: "ContainerRelativeShape"), + L(t: "修饰符-fixedSize"), + L(t: "修饰符-蒙版"), + L(t: "redacted隐私展示"), + ]), + L(t: "视图协议",sub: [ + L(t: "视图协议-简介"), + L(t: "视图协议-核心协议"), + L(t: "Style协议"), + L(t: "小组件协议"), + L(t: "Shapes协议"), + L(t: "Animations协议"), + L(t: "视图协议-Environment"), + L(t: "Previews协议"), + L(t: "Legacy bridges协议"), + L(t: "Responder chain协议"), + L(t: "Toolbar协议"), + L(t: "Documents协议"), + L(t: "特定情况视图协议"), + ]), + L(t: "SwiftUI-自定义样式"), + L(t: "ViewBuilder"), + L(t: "数据流", sub: [ + L(t: "SwiftUI数据流"), + L(t: "SwiftUI数据流-@State"), + L(t: "SwiftUI数据流-@Binding"), + L(t: "SwiftUI数据流-@Observable"), + L(t: "SwiftUI数据流-@Environment"), + L(t: "SwiftUI数据流-@AppStorage") + ]) + ]), + L(t: "SwiftData", icon: "swiftdata", sub: [ + L(t: "SwiftData基础"), + L(t: "创建@Model模型", icon: "plus.rectangle.on.rectangle"), + L(t: "SwiftData-模型关系", icon: "arrow.triangle.2.circlepath"), + L(t: "容器配置modelContainer", icon: "gearshape.2"), + L(t: "增删modelContext"), + L(t: "SwiftData-检索", icon: "magnifyingglass.circle"), + L(t: "SwiftData-处理大量数据", icon: "externaldrive.connected.to.line.below"), + L(t: "SwiftData多线程", icon: "arrow.triangle.branch"), + L(t: "SwiftData-版本迁移", icon: "arrow.right.arrow.left.square"), + L(t: "SwiftData-调试", icon: "ant"), + L(t: "SwiftData和CoreData"), + L(t: "SwiftData-资料", icon: "books.vertical") + ]), + L(t: "小组件", icon: "window.shade.open", sub: [ + L(t: "小组件-StaticConfiguration",icon: "doc.plaintext"), + L(t: "小组件-AppIntentConfiguration"), + L(t: "小组件-配置选项",icon: "rectangle.portrait.bottomleft.inset.filled"), + L(t: "AppIntentTimelineProvider"), + L(t: "Widget View", icon: "rectangle.grid.1x2"), + L(t: "刷新小组件", icon: "arrow.clockwise.circle"), + L(t: "小组件动画", icon: "figure.disc.sports"), + L(t: "小组件-远程定时获取数据", icon: "cloud"), + L(t: "小组件-获取位置权限更新内容", icon: "location.fill.viewfinder"), + L(t: "支持多个小组件", icon: "rectangle.grid.2x2"), + L(t: "获取小组件形状", icon: "rectangle.inset.filled"), + L(t: "小组件-Deep link", icon: "link.circle"), + L(t: "小组件访问SwiftData", icon: "externaldrive"), + L(t: "小组件-参考资料", icon: "books.vertical"), + ]), + L(t: "系统能力",icon: "apple.terminal",sub: [ + L(t: "WeatherKit", icon: "app"), + L(t: "Swift-DocC", icon: "doc.append"), + L(t: "AppIcon", icon: "app"), + L(t: "Share Extension", icon: "app"), + L(t: "Background Fetch", icon: "app") + ]), + L(t: "多线程", icon: "text.line.first.and.arrowtriangle.forward", sub: [ + L(t: "Swift Concurrency",sub: [ + L(t: "Swift Concurrency是什么"), + L(t: "async await"), + L(t: "Async Sequences"), + L(t: "结构化并发"), + L(t: "Actors"), + L(t: "Distributed Actors"), + L(t: "Swift Concurrency相关提案"), + L(t: "Swift Concurrency学习路径"), + L(t: "Swift Concurrency和Combine"), + L(t: "Concurrency技术演进") + ]), + L(t: "Combine",sub: [ + L(t: "介绍",sub: [ + L(t: "Combine是什么"), + L(t: "Combine的资料") + ]), + L(t: "使用说明",sub: [ + L(t: "publisher"), + L(t: "Just"), + L(t: "PassthroughSubject"), + L(t: "Empty"), + L(t: "CurrentValueSubject"), + L(t: "removeDuplicates"), + L(t: "flatMap"), + L(t: "append"), + L(t: "prepend"), + L(t: "merge"), + L(t: "zip"), + L(t: "combineLatest"), + L(t: "Scheduler") + ]), + L(t: "使用场景",sub: [ + L(t: "Combine网络请求"), + L(t: "Combine KVO"), + L(t: "Combine通知"), + L(t: "Combine Timer") + ]) + ]), + ]), + L(t: "图片处理", icon: "photo.stack", sub: [ + L(t: "图片处理-基础") + ]), + L(t: "动画", icon: "moonphase.waning.gibbous.inverse", sub: [ + L(t: "SwiftUI动画", icon: "play"), + L(t: "contentTransition", icon: "number.circle"), + L(t: "animation修饰符", icon: "waveform.path.ecg"), + L(t: "Transaction", icon: "arrow.right.arrow.left"), + L(t: "Matched Geometry Effect", icon: "arrow.triangle.2.circlepath"), + L(t: "PhaseAnimator", icon: "arrow.up.right.circle"), + L(t: "KeyframeAnimator"), + L(t: "布局动画", icon: "squareshape.split.2x2.dotted"), + L(t: "动画-例子", icon: "lightbulb") + ]), + L(t: "网络", icon:"point.3.connected.trianglepath.dotted", sub: [ + L(t: "截获网络请求数据"), + L(t: "网络状态检查"), + L(t: "WKWebView") + ]), + L(t: "性能优化",icon: "battery.100percent.bolt", sub: [ + L(t: "卡顿监控", sub: [ + L(t: "避免视图绘制掉帧"), + L(t: "卡顿原因"), + L(t: "防止卡顿的方法"), + L(t: "RunLoop"), + L(t: "卡死崩溃监控"), + ]), + L(t: "内存管理", sub: [ + L(t: "内存管理"), + L(t: "自动引用计数(ARC)机制"), + L(t: "iOS虚拟内存"), + L(t: "Swift内存安全性及其实现机制"), + L(t: "Swift内存操作"), + L(t: "内存分配器libMalloc"), + L(t: "检测和诊断内存问题"), + ]), + L(t: "崩溃", sub: [ + L(t: "崩溃日志"), + ]), + L(t: "IO性能", sub: [ + L(t: "IO性能-文件系统"), + L(t: "IO性能-文件读写"), + L(t: "IO性能-文件缓存"), + L(t: "文件内存映射(mmap)"), + ]), + L(t: "CPU", sub: [ + L(t: "CPU占用率"), + L(t: "CPU核数和类型"), + ]), + L(t: "启动优化", sub: [ + L(t: "启动时间",sub: [ + L(t: "OC项目启动时间"), + L(t: "Swift项目启动时间"), + ]), + L(t: "启动治理思路"), + L(t: "启动优化-工具"), + L(t: "动态库与静态库"), + L(t: "可合并库"), + L(t: "启动优化-线程任务管理"), + L(t: "启动优化-一些技巧"), + L(t: "启动优化-测试"), + ]), + L(t: "包体积", sub: [ + L(t: "包体积的影响"), + L(t: "包体积-系统优化"), + L(t: "包的分析"), + L(t: "包体积-资源优化"), + L(t: "包体积-代码优化"), + L(t: "Swift无用代码"), + L(t: "包体积-编译优化"), + L(t: "包体积-链接器优化"), + L(t: "包体积-三方库优化"), + ]), + L(t: "性能分析", sub: [ + L(t: "性能分析-工具"), + L(t: "Instruments"), + L(t: "MetricKit"), + L(t: "InApp分析工具"), + L(t: "fishhook"), + L(t: "Frida"), + ]), + L(t: "静态分析", sub: [ + L(t: "静态分析-概述"), + L(t: "静态分析-Swift语言"), + L(t: "SourceKitten"), + L(t: "SwiftSyntax"), + L(t: "Clang静态分析器"), + L(t: "静态分析-代码规范"), + L(t: "Language Server Protocol"), + L(t: "MachO"), + ]), + L(t: "动态性", sub: [ + L(t: "OC运行时"), + L(t: "Swift运行时"), + L(t: "动态库注入技术"), + ]), + L(t: "性能技术演进"), + L(t: "链接器"), + ]), + L(t: "调试", icon: "ant.circle.fill", sub: [ + L(t: "调试"), + L(t: "LLDB"), + ]), + L(t: "测试", icon: "testtube.2", sub: [ + L(t: "自动化测试"), + L(t: "XCTest"), + L(t: "测试-代码覆盖率") + ]), + L(t: "安全", icon: "cross.case", sub: [ + L(t: "安全-介绍"), + L(t: "Keychain") + ]), + L(t: "工程架构与构建",icon: "building.columns.fill", sub: [ + L(t: "架构技术演进"), + L(t: "设计模式"), + L(t: "包管理工具",sub: [ + L(t: "包管理工具-介绍"), + L(t: "Swift Package Manager"), + L(t: "CocoaPods") + ]), + L(t: "组件化模块化"), + L(t: "容器化插件化"), + L(t: "跨平台", sub: [ + L(t: "跨平台-Swift"), + L(t: "跨平台-布局渲染"), + L(t: "跨平台-大厂自研"), + L(t: "跨平台-React Native"), + ]), + L(t: "编辑器", sub: [ + L(t: "Xcode"), + L(t: "编辑器-三方工具"), + L(t: "VSCode"), + ]), + L(t: "Bazel", sub: [ + L(t: "Bazel-介绍"), + L(t: "Bazel-生成Xcode工程"), + L(t: "Bazel-依赖分析"), + L(t: "Bazel-query指令找依赖关系"), + L(t: "Bazel-远程执行配置"), + L(t: "Bazel-远程缓存配置"), + L(t: "Bazel-自定义的构建规则"), + ]), + L(t: "自动化构建流程"), + L(t: "单例"), + L(t: "程序入口点", icon: "door.right.hand.open"), + ]), + L(t: "macOS", icon: "macstudio", sub: [ +// L(t: "macOS技术演进"), + L(t: "macOS范例"), + L(t: "三栏结构"), + L(t: "全屏模式"), + L(t: "macOS共享菜单"), + L(t: "macOS剪贴板") + ]), +// L(t: "visionOS", icon: "visionpro", sub: [ +// L(t: "visionOS-介绍"), +// L(t: "visionOS-入门"), +// L(t: "visionOS-空间设计"), +// L(t: "空间计算和SwiftUI"), +// L(t: "RealityKit"), +// L(t: "Reality Composer Pro"), +// L(t: "visionOS-Model3D"), +// L(t: "visionOS-Object Capture"), +// L(t: "ARKit"), +// L(t: "Metal"), +// L(t: "visionOS-Unity"), +// L(t: "visionOS-系统能力"), +// L(t: "visionOS-空间视频"), +// L(t: "visionOS-声音"), +// ]), +// L(t: "人工智能", icon:"cpu.fill", sub: [ +// L(t: "人工智能-介绍"), +// L(t: "Apple Intelligence"), +// L(t: "Core ML"), +// L(t: "人工智能-模型训练"), +// L(t: "Create ML"), +// L(t: "人工智能-MLX"), +// L(t: "人工智能-文本"), +// L(t: "人工智能-Translation"), +// L(t: "人工智能-Writing Tools"), +// L(t: "人工智能-语音"), +// L(t: "人工智能-视觉"), +// L(t: "人工智能-Metal"), +// L(t: "使用LLM模型"), +// L(t: "使用三方大模型接口"), +// L(t: "Stable Diffusion"), +// L(t: "AI辅助开发APP"), +// L(t: "用于开发APP的提示词"), +// L(t: "人工智能-RAG"), +// L(t: "人工智能-技术原理"), +// ]), + L(t: "三方库使用", icon:"tray.2", sub: [ + L(t: "SQLite.swift的使用") + ]), +// L(t: "开源", icon:"globe.asia.australia", sub: [ +// L(t: "开源-精品项目"), +// L(t: "开源-有趣的项目"), +// L(t: "开源-天气"), +// L(t: "开源-时间"), +// L(t: "开源-学习"), +// L(t: "开源-生活"), +// L(t: "开源-理财"), +// L(t: "开源-阅读"), +// L(t: "开源-笔记"), +// L(t: "开源-音乐"), +// L(t: "开源-动画"), +// L(t: "macOS开源", sub: [ +// L(t: "macOS开源-窗口管理"), +// L(t: "macOS开源-系统监控"), +// L(t: "macOS开源-系统清理"), +// ]), +// ]), + L(t: "知识管理", icon:"lightbulb.max", sub: [ + L(t: "知识管理-介绍"), + L(t: "怎么用小册子APP做知识管理"), + L(t: "知识管理-PKM"), + L(t: "知识管理-工具"), + L(t: "知识管理-输入"), + L(t: "笔记记录方法"), + L(t: "卡片盒笔记法"), + L(t: "PARA记录法"), + L(t: "费曼学习法"), + L(t: "知识管理-CODE方法论"), + L(t: "知识管理-网状和树状"), + L(t: "知识管理-消化"), + L(t: "知识管理-输出"), + L(t: "知识管理-目的导向工作流"), + ]) + ] +} diff --git a/SwiftPamphletApp/Guide/View/GuideOutline/CSGuide.swift b/SwiftPamphletApp/Guide/View/GuideOutline/CSGuide.swift new file mode 100644 index 00000000..7d93ddf6 --- /dev/null +++ b/SwiftPamphletApp/Guide/View/GuideOutline/CSGuide.swift @@ -0,0 +1,19 @@ +// +// CSGuide.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import Foundation + +struct CSGuide { + var outline = [ + L(t: "oooo", icon: "swift", sub: [ + L(t: "oooddd"), + L(t: "oooddd"), + ]), + L(t: "oooddd"), + ] +} + diff --git a/SwiftPamphletApp/HomeUI/DataLink.swift b/SwiftPamphletApp/HomeUI/DataLink.swift index 415f620f..4859acd2 100644 --- a/SwiftPamphletApp/HomeUI/DataLink.swift +++ b/SwiftPamphletApp/HomeUI/DataLink.swift @@ -93,7 +93,14 @@ struct DataLink: Identifiable { case "Apple技术": switch type { case .content: - GuideListView() + GuideListView(listModel: GuideListModel(plModel: AppleGuide().outline, pplName: "ap")) + case .detail: + IntroView() + } + case "计算机科学": + switch type { + case .content: + GuideListView(listModel: GuideListModel(plModel: CSGuide().outline, pplName: "cs")) case .detail: IntroView() } @@ -115,7 +122,7 @@ struct DataLink: Identifiable { switch type { case .content: // 默认 - GuideListView() + GuideListView(listModel: GuideListModel(plModel: AppleGuide().outline, pplName: "ap")) case .detail: IntroView() } @@ -128,6 +135,7 @@ extension DataLink { DataLink(title: "开发手册", imageName: "", children: [ DataLink(title: "书签", imageName: "p24", color: .mint), DataLink(title: "Apple技术", imageName: "p19", color: .indigo), +// DataLink(title: "计算机科学", imageName: "p22"), // DataLink(title: "WWDC", imageName: "p22") ]), DataLink(title: "资料整理", imageName: "", children: [ diff --git a/SwiftPamphletApp/HomeUI/HomeiOSView.swift b/SwiftPamphletApp/HomeUI/HomeiOSView.swift index 1bfedfbc..7683fbe1 100644 --- a/SwiftPamphletApp/HomeUI/HomeiOSView.swift +++ b/SwiftPamphletApp/HomeUI/HomeiOSView.swift @@ -25,11 +25,37 @@ struct HomeiOSView: View { DetailView(state: $state) } else { // 首页 - GuideListView() +// GuideListView() + TaskCaseView() } } } +struct TaskCaseView: View { + var body: some View { + ScrollView { + TaskCaseUIUpdateView(isBad: false) + .onAppear { + Perf.showTime(des: "UI更新") + } + TaskCaseAnimationView(isBad: false) + .onAppear { + Perf.showTime(des: "动画视图") + } + TaskCaseBigImageView(isBad: false) + .onAppear { + Perf.showTime(des: "大图处理视图") + } + TaskCaseCacheView() + // 异步执行,计算量大会影响主线程 +// TaskCasePriorityView(isBad: true) +// .onAppear { +// Perf.showTime(des: "优先级视图") +// } + } + } // end body +} + struct DetailView: View { @Binding var state: String var body: some View { diff --git a/SwiftPamphletApp/Performance/Perf.swift b/SwiftPamphletApp/Performance/Perf.swift index 47b6b90c..56cb6cfc 100644 --- a/SwiftPamphletApp/Performance/Perf.swift +++ b/SwiftPamphletApp/Performance/Perf.swift @@ -9,6 +9,12 @@ import Foundation // 性能工具 struct Perf { + static func showTime(des: String = "") { + if let processStartTime = Perf.getProcessRunningTime() { + print("进程创建到\(des)时间: \(String(format: "%.2f", processStartTime)) 秒") + } + } + // 通过 sysctl 获取进程创建开始到当前的时间 static func getProcessRunningTime() -> Double? { var kinfo = kinfo_proc() diff --git a/SwiftPamphletApp/Performance/TaskCase.swift b/SwiftPamphletApp/Performance/TaskCase.swift new file mode 100644 index 00000000..1b285353 --- /dev/null +++ b/SwiftPamphletApp/Performance/TaskCase.swift @@ -0,0 +1,62 @@ +// +// BadCase.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import Foundation + +struct TaskCase { + func bad() { + // 读取文件 + loadFileSynchronously() + + } + + func good() { + // 读取文件 + Task { + await loadFileAsynchronously() + } + } + + // MARK: - 读取文件 + // 同步读取方式 - 会阻塞主线程 + func loadFileSynchronously() { + // 模拟耗时操作,减少循环次数并添加延迟 + var content = "" + for i in 1...10 { + content += "这是第\(i)行内容\n" + Thread.sleep(forTimeInterval: 0.3) // 每次循环暂停0.3秒 + } + print("同步读取文件成功") + Perf.showTime(des: "异步读取文件") + } + + // 异步读取方式 - 推荐使用 + func loadFileAsynchronously() async { + do { + _ = try await withCheckedThrowingContinuation { continuation in + DispatchQueue.global().async { + var content = "" + for i in 1...10 { + content += "这是第\(i)行内容\n" + Thread.sleep(forTimeInterval: 0.3) // 每次循环暂停0.3秒 + } + continuation.resume(returning: content) + } + } + + // 更新UI要在主线程 + await MainActor.run { + print("异步读取文件成功") + Perf.showTime(des: "异步读取文件") + } + } catch { + await MainActor.run { + print("读取文件失败") + } + } + } +} diff --git a/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseAnimationView.swift b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseAnimationView.swift new file mode 100644 index 00000000..cec97056 --- /dev/null +++ b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseAnimationView.swift @@ -0,0 +1,168 @@ +// +// TaskCaseAnimation.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import SwiftUI +import Combine + +struct Particle: Identifiable { + let id = UUID() + var position: CGPoint + var velocity: CGPoint + var color: Color + var size: CGFloat +} + +// 方案1:使用 @unchecked Sendable +@MainActor +final class ParticleSystem: ObservableObject, @unchecked Sendable { + @Published var particles: [Particle] = [] + private var timer: Timer? + private var cancellables = Set() + + func createParticles(at position: CGPoint, count: Int) { + // 在主线程创建大量粒子(会导致卡顿) + for _ in 0.. [Particle] { + return (0.. 1000 || newParticle.position.x < -100 || newParticle.position.x > 500 { + return nil + } + return newParticle + } + } + + func stopAnimation() { + cancellables.removeAll() + } +} + +struct TaskCaseAnimationView: View { + @StateObject private var particleSystem = ParticleSystem() + var isBad = true + + var body: some View { + ZStack { + Color.black.edgesIgnoringSafeArea(.all) + + // 绘制所有粒子 + ForEach(particleSystem.particles) { particle in + Circle() + .fill(particle.color) + .frame(width: particle.size, height: particle.size) + .position(particle.position) + } + + VStack { + Spacer() + HStack(spacing: 20) { + // 会卡顿的版本 + Button("创建1000个粒子(卡顿)") { + particleSystem.createParticles( + at: CGPoint(x: 200, y: 400), + count: 1000 + ) + } + .buttonStyle(.bordered) + .foregroundColor(.white) + + // 不会卡顿的版本 + Button("异步创建1000个粒子") { + Task { + await particleSystem.createParticlesAsync( + at: CGPoint(x: 200, y: 400), + count: 1000 + ) + } + } + .buttonStyle(.bordered) + .foregroundColor(.white) + } + .padding(.bottom, 50) + } + } + .onAppear { + particleSystem.startAnimation() + if isBad == true { + particleSystem.createParticles( + at: CGPoint(x: 200, y: 400), + count: 1000 + ) + } else { + Task { + await particleSystem.createParticlesAsync( + at: CGPoint(x: 200, y: 400), + count: 1000 + ) + } + } + } + .onDisappear { + particleSystem.stopAnimation() + } + .frame(height: 300) + } +} diff --git a/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseBigImageView.swift b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseBigImageView.swift new file mode 100644 index 00000000..2725f6d6 --- /dev/null +++ b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseBigImageView.swift @@ -0,0 +1,171 @@ +// +// TaskCaseBigImageView.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import SwiftUI +import Observation + +#if os(iOS) +@MainActor @Observable +final class ImageProcessor { + var processedImages: [UIImage] = [] + var isProcessing = false + + // 同步处理图片(会阻塞主线程) + func processImagesSynchronously() { + // 模拟加载多张大图 + let imageCount = 10 + processedImages.removeAll() + + for i in 0.. UIImage { + let targetSize = CGSize(width: 200, height: 200) + let format = UIGraphicsImageRendererFormat() + format.scale = 1 + + let renderer = UIGraphicsImageRenderer(size: targetSize, format: format) + return renderer.image { context in + image.draw(in: CGRect(origin: .zero, size: targetSize)) + } + } +} + +struct TaskCaseBigImageView: View { + @State private var processor = ImageProcessor() + var isBad = true + + var body: some View { + ScrollView { + LazyVGrid(columns: [ + GridItem(.adaptive(minimum: 100)) + ], spacing: 10) { + ForEach(Array(processor.processedImages.enumerated()), id: \.offset) { _, image in + Image(uiImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 100, height: 100) + } + } + .padding() + + VStack(spacing: 20) { + Button("同步处理图片(会卡顿)") { + processor.processImagesSynchronously() + } + .buttonStyle(.bordered) + + Button("异步处理图片") { + Task { + await processor.processImagesAsync() + } + } + .buttonStyle(.bordered) + + if processor.isProcessing { + ProgressView() + .padding() + } + } + .padding() + } + .onAppear { + if isBad == true { + processor.processImagesSynchronously() + } else { + Task { + await processor.processImagesAsync() + } + } + } + } +} +#endif + diff --git a/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseCacheView.swift b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseCacheView.swift new file mode 100644 index 00000000..2161aa54 --- /dev/null +++ b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCaseCacheView.swift @@ -0,0 +1,117 @@ +// +// TaskCaseCacheView.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import SwiftUI +import Observation + +@MainActor @Observable +final class CalculationViewModel { + var results: [Int: UInt64] = [:] + var isCalculating = false + + // 未优化版本:每次都重新计算 + func calculateWithoutCache(numbers: [Int]) { + results.removeAll() + for num in numbers { + results[num] = fibonacci(num) + } + } + + // 优化版本:使用缓存 + private var cache: [Int: UInt64] = [:] + func calculateWithCache(numbers: [Int]) { + results.removeAll() + for num in numbers { + if let cached = cache[num] { + results[num] = cached + } else { + let result = fibonacci(num) + cache[num] = result + results[num] = result + } + } + } + + // 计算斐波那契数列(计算密集型操作) + private func fibonacci(_ n: Int) -> UInt64 { + if n <= 1 { return UInt64(n) } + var a: UInt64 = 0 + var b: UInt64 = 1 + for _ in 2...n { + let temp = a + b + a = b + b = temp + } + return b + } +} + +struct ResultView: View { + let number: Int + let result: UInt64 + + var body: some View { + HStack { + Text("F(\(number)) = ") + .font(.system(.body, design: .monospaced)) + Text("\(result)") + .font(.system(.body, design: .monospaced)) + } + } +} + +struct TaskCaseCacheView: View { + @State private var viewModel = CalculationViewModel() + @State private var selectedNumbers: Set = [] + + private let numbers = Array(35...42) // 选择较大的数以显示性能差异 + + var body: some View { + VStack(spacing: 20) { + ScrollView { + LazyVStack(alignment: .leading, spacing: 8) { + ForEach(Array(viewModel.results.sorted(by: { $0.key < $1.key })), id: \.key) { number, result in + ResultView(number: number, result: result) + } + } + .padding() + } + .frame(height: 200) + .border(Color.gray.opacity(0.2)) + + VStack(spacing: 10) { + Text("选择要计算的斐波那契数:") + LazyVGrid(columns: [GridItem(.adaptive(minimum: 44))], spacing: 8) { + ForEach(numbers, id: \.self) { number in + Button(String(number)) { + if selectedNumbers.contains(number) { + selectedNumbers.remove(number) + } else { + selectedNumbers.insert(number) + } + } + .buttonStyle(.bordered) + .tint(selectedNumbers.contains(number) ? .blue : .gray) + } + } + } + + HStack(spacing: 20) { + Button("不使用缓存计算(卡顿)") { + viewModel.calculateWithoutCache(numbers: Array(selectedNumbers)) + } + .buttonStyle(.bordered) + + Button("使用缓存计算(流畅)") { + viewModel.calculateWithCache(numbers: Array(selectedNumbers)) + } + .buttonStyle(.bordered) + } + } + .padding() + } +} diff --git a/SwiftPamphletApp/Performance/TaskCaseViews/TaskCasePriorityView.swift b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCasePriorityView.swift new file mode 100644 index 00000000..adafafda --- /dev/null +++ b/SwiftPamphletApp/Performance/TaskCaseViews/TaskCasePriorityView.swift @@ -0,0 +1,171 @@ +// +// TaskCasePriorityView.swift +// SwiftPamphletApp +// +// Created by Ming on 2024/11/13. +// + +import SwiftUI +import Combine + +// 计算任务 +struct CalculationTask: Sendable { + let id: Int + let iterations: Int +} + +// 算结果 +struct CalculationResult: Sendable { + let taskId: Int + let result: Double +} + +// 视图模型 +@MainActor +final class CalculationPriorityViewModel: ObservableObject, @unchecked Sendable { + @Published var results: [Int: Double] = [:] + @Published var isCalculating = false + @Published var animationOffset: CGFloat = 0 + private var animationTimer: AnyCancellable? + + // 不当使用高优先级(会导致UI卡顿) + func runHighPriorityTasks() async { + isCalculating = true + let tasks = (1...10).map { id in + CalculationTask(id: id, iterations: 500000) + } + + // 使用高优先级运行所有任务 + await withTaskGroup(of: CalculationResult.self) { group in + for task in tasks { + group.addTask(priority: .high) { // 默认优先级 + await self.heavyCalculation(task) + } + } + + for await result in group { + results[result.taskId] = result.result + } + } + + isCalculating = false + } + + // 使用合适的优先级(UI流畅) + func runOptimizedTasks() async { + isCalculating = true + let tasks = (1...10).map { id in + CalculationTask(id: id, iterations: 500000) + } + + // 使用较低优先级运行计算任务 + await withTaskGroup(of: CalculationResult.self) { group in + for task in tasks { + group.addTask(priority: .background) { // 低优先级 + await self.heavyCalculation(task) + } + } + + for await result in group { + results[result.taskId] = result.result + } + } + + isCalculating = false + } + + // 密集计算函数 + private func heavyCalculation(_ task: CalculationTask) async -> CalculationResult { + var result = 0.0 + for i in 0..