自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(123)
  • 收藏
  • 关注

原创 八天让iOS开发者上手Flutter!(七)

上一篇文章我们已经完成首页聊天页面的导航条和列表展示,今天的任务是完成搜索cell的展示和点击之后的搜索页面的功能。自定义SearchCell新建search_cell.dart文件实现SearchCell代码SearchCell的话,因为仅仅只是展示,点击之后就进入搜索页了,应该来说是不需要状态的,所以用一个StatelessWidget就够了。然后布局的方式使用一个Container包含一个Row,Row里面包一个图片和文本就可以了。布局的方式其实多种多样,能实现就好了。完整代码如下:一

2021-08-24 18:59:02 306

原创 八天让iOS开发者上手Flutter!(六)

准备网络数据这一步不是很重要,提供一些假数据而已,不是重点嫌麻烦的可以跳过。先介绍一个网址:点击这个网址用来搭建我们需要的网络数据,注册账号非常简单,这里就不多说了。注册完成之后,新建一个仓库,简简单单取个名字就够了:之后点击进入仓库,可以看到下图:会默认生成以一个示例接口,可以看一看示例接口的生成规则。看不懂也没关系,我们直接直接上手自己新建一个接口,如图所示:点击右上角的编辑按钮进入编辑模式,新建一个响应chatlist,类型为Array。然后生成chatlist的数据,image.

2021-08-19 14:11:49 336

原创 一篇走心的iOS代码规范!

前言关于代码规范的重要性这里不做过多解释,能看到这篇文章说明你已经开始重视代码规范了(代码规范看起来是在限制你的自由和发挥,其实它是在间接的帮助你变得更优秀。)。适当的代码规范和标准绝不是消灭代码内容的创造性、优雅性,而是限制过度个性化,以一种普遍认可的统一方式一起做事,进而提高工作效率,降低沟通成本。代码的字里行间流淌着的是软件和程序员的血液,质量的提升是尽可能少踩坑、杜绝踩重复的坑,切实提升系统稳定性,码出质量根据约束力度,暂时把规范约定为2个等级,分别是 必须 和 建议。(一)命名规范1.

2021-08-13 15:52:50 413

原创 由美团文章“一款可以让大型iOS工程编译速度提升50%的工具”引出的.hmap文件(下)hmap落地

前言上篇文章由美团文章“一款可以让大型iOS工程编译速度提升50%的工具”引出的.hmap文件探索介绍了什么是hmap,有什么用!文章结尾我说会进行落地,然后就比较坑了,感觉不落地,这以后都没法交代,没法继续写文章了!后面不再写这样的话了,坑!结果展示1.创建个项目工程,如下图所示,红框为自己写的组件2.Pod目录3.使用写的插件,生成我们需要的hmap4.文件变化发现pod的xcconfig的HEADER_SEARCH_PATHS添加了hmap路径此时我们.

2021-08-11 14:19:31 649

原创 由美团文章“一款可以让大型iOS工程编译速度提升50%的工具”引出的.hmap文件探索(上)

前言前段时间,本鑫看了一篇美团的文章:《一款可以让大型iOS工程编译速度提升50%的工具》,一看标题就觉得惊讶,为什么呢?因为它能让编译速度提示50%且不是通过组件二进制化实现,我们日常的提升编译速度就是将组件编译成二进制文件导入项目。本着不清楚的就去了解的原则,就来看看怎么实现的。探索编译耗时原因在项目中我们会引入头文件,例如下图:我们在ViewController中引入了Person的头文件在我们引入头文件的时候,引入的是头文件的名称Person,那么Xcode是怎么找到这个Person文.

2021-08-07 18:40:53 784 1

原创 八天让iOS开发者上手Flutter!(五)

上篇文章,我们已经完成了通讯录的列表。这篇文章介绍完成通讯录右侧的索引条的功能。显示索引条之前我们已经做过了我的页面的布局,我的页面上有一个列表和一个拍照按钮,和我们今天要实现的索引条布局十分类似。我的页面的布局如下:通讯录界面的布局,和我的页面的布局都是使用一个Stack包含列表和其他子视图来实现。索引条是紧贴屏幕右侧,然后里面的子视图是由上至下的。所以自然的会想到使用一个Positioned包含Column来实现。Positioned和Stack的组合我们之前讲过,这两个组合起来使用,就和我们

2021-08-03 15:44:07 208

原创 八天让iOS开发者上手Flutter!(四)

上一篇文章我们已经完成了发现页面的搭建,下一步我们实现微信的我的页面我的页面在着手开发我的页面之前,先新建一个discover目录,将发现页面相关的文件统一挪动到这个目录下。这里会发现AndroidStudio一个比较特别的地方,新建一个目录后,挪动了的文件不需要重新导入头文件。AndroidStudio会在需要的地方自动补全路径。这点感觉还是蛮智能的。设置APP启动默认展示我的页面这个设置在上一篇文章开发发现页面的时候也说过了,就是修改rootPage.dart文件里_currentIndex

2021-07-31 15:44:35 273

原创 八天让iOS开发者上手Flutter!(三)

搭建项目主框架新建微信聊天,通讯录,发现,我的四个文件上一篇文章最后我们已经将APP的TabBar和四个对应的子视图搭建好了,但是每一个子视图里面肯定会有大量的代码,全部放到rootPage文件里面肯定是不合理的。所以我们为每个子视图创建单独的文件,并将代码分散到每个文件中。比如聊天页面,返回自己的Scaffold:现在我们点击切换一下tabBar的item,发现会有一些高亮的颜色,以及一个水波纹效果,这些都是MaterialApp类的theme提供的。如果想去掉这些效果,要来到main.da

2021-07-29 15:28:46 276

原创 八天让iOS开发者上手Flutter!(二)

Flutter布局AlignmentContainer类里有一个alignment属性,翻译过来应该叫对齐方式,这个属性用来控制Container的子控件相对于它自身的一个位置。在我们iOS开发中,我们知道坐标系的原点是在左上角。而在flutter中,坐标系的原点在父控件的正中心,可以使用这个alignment属性来控制子控件在父控件中的位置,它有两个参数分别是double类型的x,y。取值是-1到1,当0,0的时候表示子控件在父控件的正中心;当1,0的时候,表示子控件位于x方向上的最右侧,y方向上居

2021-07-27 14:35:33 322 1

原创 八天让iOS开发者上手Flutter!(一)

flutter现在是越来越火了,现在作为一个iOS开发,如果你不会flutter都好像不算个正常人似的?而且现在的flutter情况,有点像2012年那会儿刚刚兴起的iOS,Android开发一样,会点皮毛UI就可以提升不少身价…这些年过来,有无数的前端跨平台框架兴起。却只有flutter一家独秀,说明它还是有两把刷子的。今天这篇文章内容是基于Mac和Android Studio基础来开发flutter的,如果你还没有配置好开发环境,可以在网上搜索,或者直接到官网安装。这篇文章主要用来记录我学习flutte

2021-07-26 14:53:32 1014 1

原创 iOS开发高仿抖音,上下切换、横竖屏播放!

好久没写文章了,最近有点时间,模仿了一个抖音视频上下滑动切换播放功能,顾记录下实现方案,共勉。一、先说下大致思路:1.UITableView : Cell上展示视频第一帧图片,点赞,评论,头像等参数2.封装一个视频播放View3.定义一个属性currentIndex,并添加他的观察属性,当currentIndex属性值改变时,处理视频播放功能4.UITableView滑动代理,处理视频上下滑动动画操作5.注意,整个UITableView中,只存在一个视频播放实例方法,这样性能提升直播功能的界.

2021-07-23 14:42:20 2704 5

原创 iOS项目入口的演变过程(2021)

UISceneDelegate是什么,它和AppDelegate有什么关系,Swift中的@main又是什么,本文将带你一一了解。这篇文章将主要讲解下面几点内容:iOS13之前的AppDelegate启动项目的流程UISceneDelegate的多窗口实现逻辑UISceneDelegate和AppDelegate的关系int main()和@main单Window的AppDelegate在iOS13之前iPhone上的项目都是单windows的,AppDelegate中的- (BOOL)

2021-07-22 15:15:48 2671

原创 手把手带你撸一个网易云音乐首页(下篇)

前言Hello, 大家好,今天准备和大家继续分享如何利用 Swift 来实现一个网易云音乐的首页;上篇文章发布以后,我收获了不少小伙伴的关注与点赞,同时也得到了一些非常有用的建议,在这里再次感谢大家的认可, 你们的鼓励与建议是我技术输出路上最大的动力。MVVM好了,回到正题,在项目中我们使用了 MVVM 模式,在上一篇文章中,我们讲完了 Model 和 ViewModel, 那接下来就开始讲 View 吧!如果有小伙伴是从这篇文章进入的,不妨先从我的上一篇文章看起,这样看下来才能保证你思路的连贯性。

2021-07-20 14:52:04 462 1

原创 手把手带你撸一个网易云音乐首页(上篇)

前言Hello,大家好,近期我一直在学习用 Swift 编码,由于之前很多项目我都是用 OC 实现的,所以导致我现在对 Swift 还是处于一个学习的阶段中。为了提高自己的学习效率,每次我都会为自己定下一个短期的目标,就那这次来说吧,为了加快自己上手 Swift, 我为自己定下了的目标就是完成一个 Swift 版本的网易云音乐 App。不知道大家在学习一门新语言的时候,是如何提高学习效率的?不妨在评论区与大家交流一下。调研分析先分析一下 iOS 端网易云音乐 App 的首页,如图所示:看完后,首

2021-07-19 16:05:26 747 2

原创 Swift模式参考!

模式代表了单值或组合值的结构。例如,元组(1,2) 的结构是用逗号分隔两个元素的列表。因为模式代表一种值的结构,而不是一个任何一个特殊的值,你可以用多种值与之匹配。举个例子,模式 (x,y) 可以匹配元组 (1,2) 以及其他任何两个元素的元组。除了将一个值与模式匹配,你还可以提取组合值的部分或全部,然后把各部分绑定到常量或变量上。在 Swift 中,模式出现在变量和常量的声明中(在它们的左边),在 for-in 语句和 s

2021-07-15 13:40:44 169 1

原创 Swift声明参考!

一条声明可以在你的程序里引入新的名字和构造。举例来说,你可以使用声明来引入函数和方法,变量和常量,或者来定义 新的命名好的枚举,结构,类和协议类型。你也可以使用一条声明来延长一个已经存在的命名好的类型的行为。或者在你的 程序里引入在其他地方声明的符号。在swift中,大多数声明在某种意义上讲也是执行或同事声明它们的初始化定义。这意味着,因为协议和他们的成员不匹配, 大多数协议成员需要单独的声明。为了方便起见,也因为这些区别在swift里不是很重要,声明语句同时包含了声明和定义。GRAMMAR OF

2021-07-14 15:47:44 266

原创 Swift属性参考!

属性 提供了更多关于声明和类型的信息。在 Swift 中有两种类型的属性,一种用于声明,一种用于类型。例如,required 属性-当用于类的指定或者便利初始化声明时-指明每个子类都必须实现它的初始化函数。noreturn 属性-当用于函数或者方法的类型时-指明函数或者方法无需返回值。你可以用字符 @ 加上属性名和属性参数来指定一个属性:@属性名@属性名(属性参数)含有参数的声明属性可以为属性指定更多的信息,可以用于特殊的声明。这些属性参数&n

2021-07-12 14:58:09 180

原创 Swift语句参考!

在 Swift 中,有两种类型的语句:简单语句和控制流语句。简单语句是最常见的,用于构造表达式和声明。控制流语句则用于控制程序执行的流程,Swift 中有三种类型的控制流语句:循环语句、分支语句和控制传递语句。循环语句用于重复执行代码块;分支语句用于执行满足特定条件的代码块;控制传递语句则用于修改代码的执行顺序。在稍后的叙述中,将会详细地介绍每一种类型的控制流语句。是否将分号(;)添加到语句的结尾处是可选的。但若要在同一行内写多条独立语句,请务必使用分号。GRAMMAR OF A STATEMEN

2021-07-09 14:56:38 177

原创 Swift表达式参考!

在Swift中,一共有四种表达法:前缀表达,二分表达,简单表达,和后缀表达。Evaluating an expression returns a value, causes a side effect, or both.前缀表达和二分表达可用来在简短语句中使用运算符。简单表达从概念上讲是获取值的最简单方式。后缀表达和前缀表达和二分表达相似,都可以让你建立更为复杂的表达方式;例如函数调用和成员获取等。我们将在本章节中详细解释每种表达方式。GRAMMAR OF AN EXPRESSIONexpress

2021-07-08 14:15:26 161 2

原创 Swift类型参考!

Swift 语言存在两种类型:命名型类型和复合型类型。命名型类型是指定义时可以给定名字的类型。命名型类型包括类、结构体、枚举和协议。比如,一个用户定义的类MyClass的实例拥有类型MyClass。除了用户定义的命名型类型,Swift 标准库也定义了很多常用的命名型类型,包括那些表示数组、字典和可选值的类型。那些通常被其它语言认为是基本或初级的数据型类型(Data types)——比如表示数字、字符和字符串——实际上就是命名型类型,Swift 标准库是使用结构体定义和实现它们的。因为它们是命名型类型,因

2021-07-07 16:30:16 310

原创 Swift词法结构参考!

Swift 的“词法结构(lexical structure)”描述了如何在该语言中用字符序列构建合法标记,组成该语言中最底层的代码块,并在之后的章节中用于描述语言的其他部分。通常,标记在随后介绍的语法约束下,由 Swift 源文件的输入文本中提取可能的最长子串生成。这种方法称为“最长匹配项(longest match)”,或者“最大适合”(maximal munch)。空白与注释空白(whitespace)有两个用途:分隔源文件中的标记和区分运算符属于前缀还是后缀,(参见 运算符)在其他

2021-07-06 13:51:13 163

原创 同时使用Swift和Objective-C,怎么做?

Swift 与 Objective-C 的兼容能力使你可以在同一个工程中同时使用两种语言。你可以用这种叫做 mix and match 的特性来开发基于混合语言的应用,可以用 Swfit 的最新特性实现应用的一部分功能,并无缝地并入已有的 Objective-C 的代码中。Mix and Match 概述Objective-C 和 Swift 文件可以在一个工程中并存,不管这个工程原本是基于 Objective-C 还是 Swift。你可以直接往现有工程中简单地添加另一种语言的源文

2021-07-02 14:25:36 246

原创 如何运用Swift与C语言交互编程,建议收藏!

作为一种可与 Objective-C 相互调用的语言,Swift 也具有一些与 C 语言的类型和特性,如果你的代码有需要,Swift 也提供了和常见的 C 代码结构混合编程的编程方式。基本数据类型Swift 提供了一些和 C 语言的基本类型如char,int,float,double等价的 Swift 基本数据类型。然而,这些 Swift 的核心基本类型之间并不能隐式的相互转换,如 Int。因此,只有你的代码明确要求它们时再使用这些类型,而 Int 可以在任何你想使用它的时候使用。C 类型

2021-06-29 15:40:48 469

原创 在Swift中采用Cocoa设计模式,怎么操作?

使用 Cocoa 现有的一些设计模式,是帮助开发者开发一款拥有合理设计思路、稳定的性能、良好的可扩展性应用的有效方法之一。这些模式都依赖于在 Objective-C 中定义的类。因为 Swift 与 Objective-C 的互用性,所以你依然可以在 Swift 代码中使用这些设计模式。在一些情况下,你甚至可以使用 Swift 语言的特性扩展或简化这些 Cocoa 设计模式,使这些设计模式更强大、更易于使用。委托(Delegation)在 Swift 和 Objective-C 中,委托通常由一个定义

2021-06-28 14:44:41 142

原创 Swift中使用Cocoa数据类型,有哪些操作?

作为对 Objective-C 互用性(互操作性)的一部分,Swift提供快捷高效的方式来处理Cocoa数据类型。Swift 会自动将一些 Objective-C 类型转换为 Swift 类型,以及将 Swift 类型转换为 Objective-C 类型。在 Objective-C 和 Swift 中也有一些具有互用性的数据类型。那些可转换的数据类型或者具有互用性的数据类型被称为bridged数据类型。举个例子,在 Swift 中,您可以将一个Array值传递给一个要求为NSArray对象的方法。你也可

2021-06-26 15:03:50 133

原创 如何使用iOS原生语言编写Swift类?

互用性(互操作性)使开发者可以定义融合了 Objective-C 语言特性的Swift类。编写 Swift 类时,不仅可以继承 Objective-C 语言编写的父类,采用 Objective-C 的协议,还可以利用 Objective-C 的一些其它功能。这意味着,开发者可以基于 Objective-C 中已有的熟悉、可靠的类、方法和框架来创建 Swift 类,并结合 Swift 提供的现代化和更有效的语言特点对其进行优化。继承Objective-C的类在 Swift 中,开发者可以定义一个子类,该

2021-06-24 15:18:25 169 1

原创 OC与Swift API的交互!

互用性是让 Swift 和 Objective-C 相接合的一种特性,使你能够在一种语言编写的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,你应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的方案。互用性很重要的一点就是允许你在写 Swift 代码时使用 Objective-C 的 API 接口。当你导入一个 Objective-C 框架后,你可以使用原生的 Swift 语法实例化它的 Class 并且与之交互。初始化为了使用 Swift 实例化 Object

2021-06-23 15:25:13 179

原创 Swift与Objective-C和Cocoa混合编程的基本设置!

重要事项:这篇文章初步介绍了在开发中用到的 API 或技术。苹果公司提供这些信息来帮助您规划本文所说明的技术和接口以用于苹果的产品上。这些信息会改变,并且根据这篇文章所实现的软件应该在最新的操作系统并根据最新的文档测试。本文档的新版本,可能在未来通过技术和 API 的 seeds 版本来提供Swift 被设计用来无缝兼容 Cocoa 和 Objective-C 。在 Swift 中,你可以使用 Objective-C 的 API(包括系统框架和你自定义的代码),你也可以在 Objective-C中 ..

2021-06-22 19:14:00 171

原创 iOS开发-Swift进阶之泛型!

swift进阶总汇本文主要介绍泛型及其底层原理泛型泛型主要用于解决代码的抽象能力 + 代码的复用性例如下面的例子,其中的T就是泛型func test<T>(_ a: T, _ b: T)->Bool{ return a == b}//经典例子swap,使用泛型,可以满足不同类型参数的调用func swap<T>(_ a: inout T, _ b: inout T){ let tmp = a a = b .

2021-06-15 15:48:49 285 4

原创 iOS开发-Swift进阶之协议Protocol!

swift进阶总汇本文主要分析protocol的用法及底层存储结构协议的基本用法【语法格式】:协议的语法格式//协议的语法格式protocol MyProtocol { //body}class、struct、enum都可以遵守协议,如果需要遵守多个协议,可以使用逗号分隔//1-2、class、struct、enum都可以遵守协议,如果需要遵守多个协议,可以使用逗号分隔struct CJLTeacher: Protocol1, Protocol2 { //b.

2021-06-12 15:38:54 304 4

原创 iOS开发-Swift进阶之访问控制权限!

swift进阶总汇主要介绍swift中的访问控制权限关键字private1、private:访问级别仅在当前定义的作用域内有效(单例中使用过)//8-1、private:访问级别`仅在当前定义的作用域内有效class CJLTeacher{ static let shareInstance = CJLTeacher() private init(){}}var t = CJLTeacher.shareInstancefilePrivatefilePrivate:访问.

2021-06-10 15:56:15 315 1

原创 iOS开发-Swift进阶之可选类型Optional & Equatable+Comparable协议!

swift进阶总汇本文主要分析Optional源码、Equatable+Comparable协议Optional分析swift中的可选类型(Optional),用于处理值缺失的情况,有以下两种情况有值,且等于x没有值这点可以通过swift-source->Optional.swift源码(CMD+P,搜索Optional)源码来印证@frozenpublic enum Optional<Wrapped>: ExpressibleByNilLiteral {.

2021-06-08 14:49:49 338

原创 iOS开发-Swift进阶之闭包,逃逸闭包 & 非逃逸闭包!

swift进阶总汇本文主要分析逃逸闭包 、非逃逸闭包、自动闭包逃逸闭包 & 非逃逸闭包逃逸闭包定义当闭包作为一个实际参数传递给一个函数时,并且是在函数返回之后调用,我们就说这个闭包逃逸了。当声明一个接受闭包作为形式参数的函数时,可以在形式参数前写@escaping来明确闭包是允许逃逸的如果用@escaping修饰闭包后,我们必须显示的在闭包中使用selfswift3.0之后,系统默认闭包参数就是被@nonescaping,可以通过SIL来验证1、执行时机:在函数体内.

2021-06-04 16:39:43 380

原创 iOS开发-Swift进阶之闭包,使用&捕获原理!

swift进阶总汇本文主要分析闭包以及闭包捕获变量的原理闭包闭包是一个捕获了全局上下文的常量或者变量的函数,通俗来讲,闭包可以是常量也可以是函数【全局函数是一种特殊的闭包】:定义一个全局函数,只是当前的全局函数并不捕获值func test(){ print("test")}【函数闭包】:下面的函数是一个闭包,函数中的incrementer是一个内嵌函数,可以从makeIncrementer中捕获变量runningTotalfunc makeIncrementer().

2021-06-03 16:42:49 499 1

原创 iOS开发-Swift进阶之枚举enum!

swift进阶总汇本文主要介绍enum的常见使用形式,以及枚举大小是如何计算的补充:添加脚本自动生成SIL通过target -> +,选择 other -> Aggregate,然后命名为CJLScript选中CJLScript,选择Build Phases -> New Run Script Phase在Run Script中输入以下命令swiftc -emit-sil ${SRCROOT}/06、EnumTest/main.swift | xcr.

2021-06-02 15:37:20 765 1

原创 iOS开发-Swift进阶之Mirror源码解析!

swift进阶总汇本文主要是分析Mirror的底层实现,以及根据Mirror底层原理仿写其结构的实现在上篇“反射Mirror & 错误处理”文章中,我们介绍了Mirror的使用,即JSON解析,对此我们有如下一些疑问:1、系统是如何通过Mirror获取对应的属性以及值的?2、Swift众所周知是一门静态语言,系统在底层到底做了什么,使swift具有了反射的特性呢?下面我们来对Mirror的底层实现进行探索Mirror底层源码分析反射的API主要是由两部分实现的一.

2021-06-01 16:04:54 616

原创 iOS开发-Swift进阶之反射Mirror & 错误处理!

swift进阶总汇本文主要介绍Mirror的使用以及使用Mirror进行JSON解析的错误处理反射Mirror反射:是指可以动态获取类型、成员信息,在运行时可以调用方法、属性等行为的特性,在上面的分析中,我们已经知道,对于一个纯swift类来说,并不支持直接像OC runtime那样的操作但是swift标准库依旧提供了反射机制,用来访问成员信息,即Mirror一般使用class CJLTeacher: NSObject { var age: Int = 18}le.

2021-05-31 15:21:33 399

原创 iOS开发-Swift进阶之内存管理 & Runtime!

本文主要介绍swift中的内存管理,涉及引用计数、弱引用、强引用、循环引用、Runtime等内存管理 - 强引用在swift中也是使用ARC来追踪和管理内存的,下面我们通过一个案例来进行分析class CJLTeacher { var age: Int = 18 var name: String = "CJL"}var t = CJLTeacher()var t1 = tvar t2 = t查看t的内存情况,为什么其中的refCounts是0x000000060000

2021-05-29 16:32:59 411

原创 iOS开发-Swift进阶之指针!

本文主要介绍swift中的指针swift中的指针分为两类typed pointer 指定数据类型指针,即 UnsafePointer<T>,其中T表示泛型raw pointer 未指定数据类型的指针(原生指针) ,即UnsafeRawPointerswift与OC指针对比如下:SwiftOC说明unsafePointerconst T *指针及所指向的内容都不可变unsafeMutablePointerT *指针及其所指向的内存内容均可

2021-05-28 14:48:04 402

原创 iOS开发-Swift进阶之值类型 & 引用类型!

本文主要介绍为什么结构体是值类型,类是引用类型值类型图片看不了请前往简书前提:需要了解内存五大区,,如下所示[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XFIDtehX-1622094844717)(//upload-images.jianshu.io/upload_images/2251862-fa758fb4cd141db2.jpg?imageMogr2/auto-orient/strip|imageView2/2/w/467/format/webp)]

2021-05-27 13:56:22 378 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除