Hi there 👋

Welcome to my blog

写给iOSer的实践指南 如何快速上手Android项目

理解Gradle的各种配置文件 setting.gradle文件 项目根build.gradle文件 模块的build.gradle文件 Plugin Android Android四大组件 activity service content provider broadcast receiver Intent 资源管理 资源目录结构: 配置限定符: 资源访问: 理解Gradle的各种配置文件 当Android studio创建新项目时,默认会生成三个Gradle文件。 其中两个,setting.gradle和build.gradle在项目根目录中。另一个build.gradle在应用程序模块中。 如下所示 MyApp | - build.gradle | - setting.gradle | - app 这三个文件每一个都有其独有的用处。 setting.gradle文件 setting文件在Build初始化阶段执行,定义了哪些模块应改被包含在构建中。 单个模块项目不一定需要setting文件,但是多模块项目必须要包含setting文件;否则,Gradle不知道要将哪些模块包含到构建中。 include ':app' 如上所示:app模块被包含其中。 项目根build.gradle文件 在项目根目录的build.gradle文件中,你可以配置需要应用于项目中所有模块的选项。它默认包含两个代码块: buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' } } allprojects { repositories { jcenter() } } buildscript代码块是配置实际构建的位置。 在**repositories{…}**代码块中,可以看到我们在 repositories{} 中将JCenter配置为依赖库。 依赖库意味着依赖的来源,或者换句话说,一个可下载的第三方库列表,我们可以在我们的应用和库中使用。 JCenter是一个Gradle预先内置的Maven存储库,Gradle默认已经配置好相关了,不需要你额外的设置 。 Gradle中还有几个内置的存储库,并且Gradle也支持添加自己的本地或远程仓库。...

October 10, 2023 · Jdy

我的第一个Clang插件

概念 编译的主要流程 输入文件 预处理 编译阶段 后端 链接 绑定 如何利用Clang提升开发质量 Clang提供了什么能力? libClang Clang Plugins LibTooling 我的第一个Clang插件 编译 llvm-project 编写clang plugin的准备工作 编写clang plugin Xcode集成Clang插件 指定clang 关闭 Enable Index-While-Building Functionality 指定需要额外加载的clang plugin 编译结果 我的第一个LibTooling 使用ninja编译llvm项目 创建libtooling 使用LibTooling 概念 LLVM Low Level Virtual Machine,由 Chris Lattner(Swift 作者) 用于 Objective-C 和 Swift 的编译,后来又加上了很多功能可用于常规编译器、JIT 编译器、调试器、静态分析工具等。总结来说,LLVM 是工具链技术与一个模块化和可重用的编译器的集合。 Clang 是 LLVM 的子项目,可以对 C、C++和 Objective-C 进行快速编译,编译速度比 GCC 快 3 倍。Clang 可以认为是 Objective-C 的编译前端,LLVM 是编译后端,前端调用后端接口完成任务。Swift 则有自己的编译前端 SIL optimizer,编译后端同样用的是 LLVM。 AST 抽象语法树,按照层级关系排列。 IR 中间语言,具有与语言无关的特性,整体结构为 Module(一个文件)–Function–Basic Block–Instruction(指令)。 编译器 编译器用于把代码编译成机器码,机器码可以直接在 CPU 上面运行。好处是运行效率高,坏处是调试周期长,需要重新编译一次(OC 改完代码需要重新运行)。 解释器 解释器会在运行时解释执行代码,会一段一段的把代码翻译成目标代码,然后执行目标代码。好处是具有动态性,调试及时(类似 Flutter、Playground),坏处是执行效率低。平时在调试代码的时候,使用解释器会提高效率。 编译的主要流程 通过命令行查看源码的编译流程...

May 30, 2023 · Jdy

玩转StableDiffusion

玩转 Stable diffusion(落地实操版) 什么是 Midjourney、Stable Diffusion 为什么选择 Stable Diffusion? 开发环节,先在iOS上跑起来(简述) Core ML Stable Diffusion 下载模型 模型解压缩 生成 StableDiffusionPipeline 文生图 证书设置 最终效果 在各种设备上把 Stable Diffusion 玩起来 iOS MacOS Draw Things App Stable Diffusion WebUI SD Web UI 环境搭建 (略) Windows PC 云服务器 傻瓜式部署流程 不同方案的优势和限制 iPhone、iPad Mac OS 使用 Draw Things App: 使用 Stable Diffusion Web UI Windows PC 使用 Stable Diffusion Web UI 云服务器 使用 Stable Diffusion Web UI 手把手教你生成一张专业摄影图 手把手教你给模特换装 ControlNet的其他妙用 玩转 Stable diffusion(落地实操版) 什么是 Midjourney、Stable Diffusion 举个例子:...

May 30, 2023 · Jdy

VSCode中使用正则查找替换

在VSCode中打开正则 引入问题 想要查找所有以双引号 “” 导入的头文件 #import “People.h” 将所有双引号导入的头文件替换为尖括号 #import <People/People.h> 解决问题 查找所有以 #import " 开头, .h" 结尾的字符串 替换为以 #import <ACKShareKit/ 开头,> 结尾的字符串 捕获组为(.*.h) 参考链接

February 2, 2023 · Jdy

使用Property Wrapper创建Weak Array

Property Wrapper是什么 使用Property Wrapper创建Weak Array Property Wrapper是什么 属性包装器是Swift 5的一项强大功能。 为了更好的了解属性包装器,让我们举一个例子来看一下它们能解决哪些问题。 假如我们想要添加一个日志记录功能,每次属性更改时,我们都会将其新值打印到Xcode控制台。 这样追踪错误或追踪数据流时非常有用。 实现此目的的直接方法是覆盖setter: struct Bar { private var _x = 0 var x: Int { get { _x } set { _x = newValue print("New value is \(newValue)") } } var bar = Bar() bar.x = 1 /// print 'New value is 1' } 如果我们继续记录更多的这样的属性,那么代码很快就会变得一团糟。 为了不用每个新属性一遍又一遍的复制相同代码,我们声明一个新类型,该新类型将执行日志记录: struct ConsoleLogged<Value> { private var value: Value init(wrappedValue: Value) { self.value = wrappedValue } var wrappedValue: Value { get { value } set { value = newValue print("New value is \(newValue)") } } } 这是我们如何使用ConsoleLogged重写Bar的方法:...

November 7, 2022 · Jdy