自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(50)
  • 问答 (1)
  • 收藏
  • 关注

原创 笔记:git命令大汇总+关键命令理解

前言:git是用起来很简单,有时候遇到特殊情况,忘记了哪个命令总不免查找一番,这里做一个统计,以便用时查看首先前面我不会去按顺序介绍git,比如简介、安装等等.前面我会直接介绍创建版本、版本回退、删除等等操作,因为我相信大家都是熟悉git,如果兴趣的的可以看看博客后面的,简介、诞生、等等一些知识点,话不多说,马上开始基本的linux命令学习1. cd:改变目录2. cd..:回到上一个目录,直接cd进入默认的目录3. pwd:显示当前所在的目录路径4. ls: 查...

2021-04-30 15:56:12 573 2

原创 耶,这些面试题有点歪,你会吗?

这次给大家分享一些面试题,你知道答案吗?第一道面试题:请看下面的代码,请问输出的结果是什么?第二道面试题:请看下面的代码,请问输出的结果是什么?第三道面试题:请看下面的代码,请问输出的结果是什么?第四道面试题:请看下面的代码,请问着2块代码会发生什么事?面试题答案1.第一道:相信我们心中都是已经有答案了,现在我们一个一个来看看每一道面试题,其实考察的还是我们的基础的问题,涉及的都是某一个知识点,首先第一道.这样我们先看一下运行结果:1和3

2021-04-26 13:58:17 194 2

原创 解决线程同步的方案汇总总结

这是一篇继上一篇继续介绍多线程同步的博客.(你了解多线程自旋锁、互斥锁、递归锁等锁吗?)GNUstep介绍再介绍其他锁之前我们先看一个其他的知识点.我们知道在Foundation框架下,苹果公开的源码只有NSObject,而我们想知道的NSString、NSArray、NSRunLoop、NSThread等等都是没有给源码的.只给了NSObject的部分实现,如果我们确实想看这些源码的话.通过汇编,打断点一步一步看,这样也是可以看到的,但是这样就有点麻烦,要会汇编语言,而且还要一点一点的调试才能知道

2021-04-25 17:07:54 768 5

原创 你了解多线程自旋锁、互斥锁、递归锁等锁吗?

首先看一下问题引出,先看一些经典的问题.多线程的隐患首先我们利用多线程的话肯定是好处多多,因为我们可以同时去做一些事情,大大的提高了效率.像我们下载视频的时候就可以同时下载多个视频,这样是节省了很多时间,用户体验也会更好.但是用得时候也会存在一些安全隐患,比如同一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源,这样会出现一些数据错乱和数据安全的问题.下面我们就看一些例子.存钱取钱案例比如我现在有1000元,同时有2个线程去处理,一个线程是取钱100元,一个线程是存钱100元,

2021-04-22 17:02:09 4000 9

原创 多线程基础知识+17个字判别死锁

我们在面试的时候经常会遇到很多关于多线程的面试题,这些面试题的答案你都知道吗?1.你理解的多线程是什么?2.iOS的多线程方案有哪些?你更倾向于哪一种?为什么?3.你在项目中用过GCD吗?有哪些使用?4.GCD的队列类型有哪些?5.什么情况下会产生死锁?6.说一下OperationQueue和GCD的区别,以及各自的优势是什么?7.线程安全的处理手段有哪些?8.OC你了解的锁有哪些?在你回答的基础上进行二次提问;追问一:自旋锁和互斥锁对比?追问二:使用以上锁需要注意哪

2021-04-21 10:04:39 621 10

原创 你了解RunLoop线程保活吗?已封装好,2句代码直接使用

如果你没有了解RunLoop的一些基础,建议你看看这2篇博客,对线程保活本质理解有很大帮助中高级iOS必备知识点之 RunLoop(一)源码解读RunLoop,理解以后面试必加分(温馨提示:这里是一步一步探究,步骤过程比较多,如嫌弃啰嗦,可直接拿后面封装的代码直,2句即可完美使用.)我们面试中经常遇到很多面试官,问我们关于RunLoop的知识点,可能我们大多数人了解RunLoop,但在项目中,我们真正用到RunLoop还是比较少的,RunLoop其实应用场景还是比较多,比如我们的定时器、线程

2021-04-15 22:54:47 281 1

原创 源码解读RunLoop,理解以后面试必加分

继上一篇博客中高级iOS必备知识点之RunLoop(一)继续介绍RunLoop的状态首先我们去RunLoop的源码去查看它有几种状态,如下图:它一共有上面的这几种个状态/* Run Loop Observer Activities */typedefCF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {kCFRunLoopEntry = (1UL << 0), //即将进入loopkCFRunLoopBeforeTime.

2021-04-13 12:57:57 781 2

原创 中高级iOS必备知识点之 RunLoop(一)

RunLoop学习起来是很抽象,也不好理解,所以一定多看几次,多学学才能学好!这也是中高级iOS必须掌握的知识点,面试中经常遇到.什么是 RunLoop?Run 表示运行,Loop 表示循环。结合在一起就是运行循环的意思。RunLoop就是在程序运行过程中循环做一些事情.RunLoop的应用范畴有哪些?定时器(Timer)、PerformSelectorGCD Async Main Queue事件响应、手势识别、界面刷新网络请求AutoreieasePool上面这些底层都

2021-04-08 14:51:56 3190 5

原创 什么是Runtime?平时项目有用到过吗?

我们在面试中经常会被问到这些问题,到底怎么回答比较合适?这样我们先去看一下我们平时项目中用到的Runtime,等下我们再来概括上面的问题的答案.我们肯定是用Runtime提供的API去做一些事情.我们肯定是多多少少有接触Runtime,如果面试官问你,你肯定回答用过,不然说明你对Runtime一点都不了解.这样对你的印象就大打折扣了.现在我就列一些我们可能用到的API(注意只是部分,不是所有).Runtime类相关的APIRuntime成员变量相关的APIRuntime属性相

2021-04-07 10:22:01 467 1

原创 作为iOS开发,这道面试题你能答出来,说明你基础很OK!

首先我们先来看一下这道面试题是啥?题目的描述非常少,我是先创建了一个继承NSObject的GDPerson类;GDPerson类的.h文件GDPerson类的.m文件再看一下我们viewController.m里面的代码:这是题目请问:1.print能不能调用成功?如果不能会怎么样?如果能的话调用结果是什么?这个又是一个更扯的面试题,真正开发的时候,谁也不会这么写,这个还是主要考你基础!相信你看到这个题目之后应该心中已经有了答案,要不知道结果,要么可能知道结果

2021-04-02 18:38:11 1458 6

原创 深入理解isKindOfClass、isMemberOfClass、synthesize、dynamic区别

一、isKindOfClass、isMemberOfClass区别跟大家分享一道关于isKindOfClass和isMemberOfClass的面试题,也是比较常见的面试题,请看下面的代码:请问当前控制台的打印是多少?这些题目看着特别的扯淡,为什么呢?首先我们在现实开发中绝对不会这么去写,也不会这么去判断,这也是主考官想知道你对这个知识点是否了解.这里也是考察我们对类对象,元类对象对使用isKindOfClass和isMemberOfClass的使用情况.首先我们先创一个建命令行的项目,因为

2021-04-01 16:48:10 928 1

原创 从源码理解runtime之super、superclass知识点

跟大家分享一道关于super和superclass的面试题,也是比较常见的面试题,请看下面的代码:请问当前的4个结果输出是多少?我们平时写代码估计也不会这么写,面试官问你这些问题,主要是看你对super和superclass是否理解透彻,接下来我们就去分析一下.首先我们肯定是知道[selfclass]这个肯定就是当前类,也就是GDStudent;而[selfsuperclass]肯定是它的父类GDPerson这两个应该是毫无疑问,我们看一下是不是这样,请看下图代码:这两个..

2021-04-01 13:00:56 457 1

原创 关于runtime的消息机制,你看我就够了!

在上一个博客我们介绍了,消息机制的第一个阶段超级详细的Runtime的消息机制的消息发送阶段,现在我们继续来探究消息机制的的第二三阶段.消息机制发送阶段的回顾之前的一幅图标记的很清楚,这里我就用文字叙述一下:1.首先会判断传入的receiver是不是为空,为空就退出报错,如果不为空继续执行2.再从receiverClass的cache中查找方法,如果找到方法就调用结束,找不到方法就会继续从receiverClass的class_rw_t中的方法列表中查找方法,如果找到就调用结束退出,并把方.

2021-03-31 16:37:46 941 1

原创 超级详细的Runtime的消息机制的消息发送阶段

通过之前博客的介绍,这个博客我们来介绍objc_msgSend,相信很多小伙伴在面试的时候,经常遇到面试官问:你知道runtime的消息机制吗?等等关于runtime的知识点,学会了runtime不止让我们面试中能增加亮点,也会为我们开发中提高很多便利!通过这个博客你将学习到消息机制的三大阶段的消息发送具体是怎么执行的,详细的介绍底层甚至汇编语言执行的过程,详细仔细学习下来你会收获不少!好了,话不多说,lets begin!objc_msgSend三大阶段:消息发送、动态方法解析、消息转发首先我

2021-03-30 13:36:53 285 3

原创 Runtime学习基础之class结构之散列表(哈希表)

上次我们学习runtime的isa,这节课我们继续学习runtime的class结构,这个博客我们主要说class的cache_t cache这个散列表(哈希表),主要是为了让我们更深刻的理解调用过程,通过这个博客,你将学习到:通过Runtime调用对象方法的过程的更深刻的理解我们以前如果面试官问你,一个对象调用对象方法的过程是什么样的?你可能会回答:instance通过isa找到类对象,然后调用对象方法,如果找不到就通过superclass找到父类寻找instance方法....通过这个博客,你就

2021-03-29 17:18:01 206 3

原创 Runtime学习基础之isa指针(终结篇)

如果您在看这篇博客时候,还没看过我上一篇博客,需要您去耐心的看一下,有助于更快更好的理解这篇博客的内容Runtime学习基础之isa指针好,我们继续上篇博客继续说:我们先用结构体解决这个问题,请看下面的代码这里我们定义一个结构体,里面存储3个参数,我们看一下结果能不能解决这个问题:请看下面的代码截图这个明显是解决了情况,大家可以尝试其他情况,接下来,我们就引入今天最重要的模块,就是共同体union首先我们先看我们这个需求怎么用共用体union来解决,这里我直接写结果,等会再.

2021-03-28 21:35:19 296 1

原创 Runtime学习基础之isa指针

重要的事情说三遍:重要提示:你要想学习并且学好Runtime,首先你要了解它底层的一些常用的数据结构,比如isa指针重要提示:你要想学习并且学好Runtime,首先你要了解它底层的一些常用的数据结构,比如isa指针重要提示:你要想学习并且学好Runtime,首先你要了解它底层的一些常用的数据结构,比如isa指针首先问大家一个问题,如果问你对isa了解吗?我估计你的答案基本就是:实例对象的isa指向类对象,类对象的isa指向元类对象;当调用对象方法的时候,通过instance的isa找

2021-03-26 17:14:25 1120 2

原创 关于block的循环引用,你看我就够了!

开篇:如果你之前看过我block的其他的文章,你会更容易今天这篇博客的一些更深的解释,每篇只有一个知识点,基本上把这些都看了,block基本不会有什么问题的,基本都是掌握了.block的源码解读之变量捕获机制(capture)从源码、ARC、MRC带你理解block的三大类型深入理解block的底层之copy深入理解block的底层之对象类型的auto变量深入理解__block修饰符的底层实现原理循环引用:在平时开发过程中,block是我们经常使用的功能,如果不多加注意就会造

2021-03-24 23:26:10 1631 9

原创 深入理解__block修饰符的底层实现原理

在介绍今天的博客之前,你应该了解,block的三大类型,block的变量捕获机制,哪些情况下是NSMallcBlock,这些内容我前面的博客都有介绍的非常清楚,相信你看了会有很多收获.通过这篇博客的学习,你将会了解到:__block它当修饰符的时候,它的底层到底是怎么实现的.首先看下面的代码:这里为什么去修改变量的值会报错,大家知道吗?这时候我们去把当前的main.m文件转成c++文件,因为我们知道oc的底层就是c/c++,然后是汇编语言,然后是机器语言,可以通过下面的命令在终端执行:(

2021-03-23 18:35:40 1992 9

原创 深入理解block的底层之对象类型的auto变量

上一个博客我们介绍的都是block是基本类型的数据变量,这个文章,你将了解block访问对象类型的auto变量将是什么情况请看下面的代码:ARC环境下运行首先上面的代码我们是非常清楚,当person离开了自己的大括号作用域,它就会释放!再请看下面的代码:ARC环境下运行这种情况请问到断点前,person会不会释放?答案:不会释放,因为block是mallocBlock,它对person是强引用吧,只有等block释放了,person才有可能释放!这时候我们来看一下源码(前

2021-03-22 21:57:15 330 3

原创 深入理解block的底层之copy

由于block涉及的东西稍微多点,所以您看这篇博客之前,最好是看一下我的上一篇博客中,这样更有助于你理解从源码、ARC、MRC带你理解block的三大类型好,接下来我们继续讨论block的底层之copy,首先先看这张图,在我们实际的运用中,我们用得最多的是__NSMallocBlock,因为很多时候,我们都是把block定义在那里,等到想用的时候才去调用,那么说明这种block都是__NSMallocBlock,看图我们知道__NSMallocBlock:就是__NSStackBlock调用

2021-03-21 12:50:25 257 3

原创 从源码、ARC、MRC带你理解block的三大类型

首先,在了解block三大类型之前,我们需要了解一个知识:(温馨提醒:如果我的之前博客你没有看,有些概念你不清楚的话,你可能很难理解,如果前面你都看了,这篇博客你看就像切菜一样简单!)程序的内存分配一个由C/C++编译的程序占用的内存分为以下几个部分栈(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式类似于链

2021-03-20 22:45:20 365 9

原创 block的源码解读之变量捕获机制(capture)

我们在面试的时候经常被问到block,而且也是iOS的特别常见的面试题.比如:1.block的原理是怎么样的?本质是什么?2._block的作用是什么?有什么使用注意点?3.block的修饰词为什么是copy?使用block有哪些使用注意?4.block在修改NSMutableArray,需不需要添加_block?接下来带你轻轻松松解读源码,先了解block的本质,我们先创建一个最简单的block如下;这一个简单的block,我们先用终端把main.m这个文件转成c++代码,我们

2021-03-19 17:55:04 291 2

原创 iOS底层之关联对象

首先我们来回忆一个经典的面试题Category能否添加成员变量?如果可以,如何给Category添加成员变量?首先由之前的知识我们知道,Category在底层生成的如下从上面的结构我们都能看出来,并没有属性的定义,所以并不能直接添加,到底如何呢?,OK,我们继续探索.接下来我们就一步一步的探索:首先我先创建一个继承NSObject的GDPerson,在创建一个GDPerson+Test的分类]如下:我们知道,在GDPerson中的age它是系统给我们生成了3个:成员变量;

2021-03-18 10:55:30 2228 16

原创 Category的底层分析之initialize

这篇博客我们将围绕这几个问题来探究initialize.1.+initialize方法详解2.load、initialize方法的区别是什么?它们在category中的调用顺序?以及出现继承时他们之间的调用过程?首先看我的截图,我们先看一下initialize会不会像load一样,runtime加载类、分类的时候就会调用.还是一样,我创建GDPerson类和Test1、Test2分类,里面分别调用了initialize方法,如下:从这可以看出,initialize并没有调用,这里我们

2021-03-17 11:18:56 1013 1

原创 Category的底层分析之load

今天我们就围绕一个面试题来从源码的角度分析答案!一、Category中有load方法吗?load方法是什么时候调用的?load方法能继承吗?如果分类又存在继承是如何加载load顺序的呢?首先我们先看下下面的代码,我们先看代码运行结果,再从源码上分析!GDPerson.m文件里面+(void)load{ NSLog(@"GDPerson+load"); }GDPerson+Test1.m文件里面+(void)load{ NSLog(@"GDPerson+Test1+load");}GDPer.

2021-03-16 13:31:47 221 1

原创 Category的底层分析

这篇文章我们将针对2个问题来研究:一、Category的实现原理?二、 Category和Extension的区别是什么?简介:Category是Objective-C 2.0之后添加的语言特性,分类、类别其实都是指的Category。Category的主要作用是为已经存在的类添加方法。Objective-C 中的 Category 就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。知识回顾:上面截图就是Category的具体实现

2021-03-15 13:05:16 1368 13

原创 KVC的底层分析

首先抛出最常见的关于kvc的两个面试题:1.kvc的赋值和取值过程是怎么样的?原理是什么?2.通过kvc修改属性会触发kvo吗?这篇文章就是围绕这2个问题来阐述的,相信你看完了一定会对这两个问题有一个深刻的了解.KVC回顾KVC(Key-value coding)键值编码,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值。而不需要调用明确的存取方法。这样就可以在运行时动态地访问和修改对象的属性。而不是在编译时确定,这也是iOS开发中的黑魔法之一。很

2021-03-14 15:10:50 330 5

原创 探索KVO的本质(二)

通过探索kvo的本质(一)我们已经了解到很多关于kvo的基础知识,接下来我们看下面的代码:我们知道:通过[** class]和object_getClass(**) 都能获取实例对象的类对象,而从上面的运行结果,我们很容易知道,通过runtime的object_getClass(**)获取的就是它的真实的类对象,而[** class]获取的是它的什么?还记得上一个博客的图吗?这里直接说结论,是因为[self.person1 class],class方法由于看不到源码,但是我们可以猜.

2021-03-13 17:36:44 171 1

原创 探索KVO的本质是什么?

概述KVO全称KeyValueObserving,是苹果提供的一套事件通知机制。允许对象监听另一个对象特定属性的改变,并在改变时接收到事件。由于KVO的实现机制,所以对属性才会发生作用,一般继承自NSObject的对象都默认支持KVO。KVO和NSNotificationCenter都是iOS中观察者模式的一种实现。区别在于,相对于被观察者和观察者之间的关系,KVO是一对一的,而不一对多的。KVO对被监听对象无侵入性,不需要修改其内部代码即可实现监听。KVO可以监听单个属性的变化,也可以监听集合

2021-03-12 11:08:54 331 4

原创 深入探究对象的isa指针指向哪里

首先我们之前知道isa的指针的指向结论是:1.instance对象的isa指向class对象2.clsaa对象的isa指向meta-class3.meta-class对象的isa指向基类的meta-class对象(NSObject的isa和superclass区别)这篇博客,我们将探究isa指针指向哪里?并且会从代码层的内存地址证明isa指针的指向。首先instance对象的isa指针指向class对象,我们就可以创建一个instance对象从上面的截图运行结果可以看出stu

2021-03-11 14:43:41 324 1

原创 NSObject的isa和superclass区别

这篇博客介绍的就是网上很流行的一张图关于isa和superclass的关系的解释!温馨提示:如果你没有接触类的对象不了解的话,这篇博客有点费解,建议先看一下深入探究NSObject对象。一、isa首先看下面的代码@interfance GDStudent : GDPerson@interfanceGDPerson:NSObject我们知道GDStudent的class的内存中存储的有:isa、superclass、对象方法、属性、协议、成员变量 等等。我们知道GDP...

2021-03-10 13:51:15 209 1

原创 深入探究NSObject对象

首先如果面试官问你:NSObject对象有哪几种类型?实例对象(instance)、类对象(class)、元类对象(meta-class)三种。实例对象就不说了,接下来我们探究类对象提问:一个NSObject类对象有几个?请看下面代码:从上面执行的代码可以看出,5个输出的结果一摸一样,实际上他们都是一个对象,每个类在内存中有且只有一个class对象。提问:一个NSObject元类对象有几个?请看下面的代码:从上面执行的代码可以看出,5个输出的结果一摸一样,实际上

2021-03-09 17:35:13 229 3

原创 关于runtime的objc_getClass和object_getclass

一、objc_getClass首先我们看一下objc_getClass的内部实现是:objc_getClass(constchar*_Nonnullname) 从这里只能看出需要传入一个字符串的类名, Returns the class definition of a specified class 返回对应的类对象。请看下面的截图从这里可以看出是runtime的相关的,我们就可以从苹果开源的源码查看分析(源码链接下载链接 找到objc目录下,打开下载数字最大的,代表最新的...

2021-03-09 11:13:07 370 1

原创 探索NSObject对象的本质

大家在iOS面试的时候,是否遇到这样的面试题:一个NSObject对象占用多少内存?(我们知道不同的平台支持的代码肯定是不一样的,这里是讨论iOS下64bit (arm64))。首先这个Objective-C的底层是C或者C++,然后是汇编语言,再然后是机器语言!首先我们用malloc_size函数来获取一下分配的内存大小答案是:16字节但是这个答案是怎么来的呢?我们来探究一下!首先底层既然是c++,我们把代码转换一下c++代码看一下底层实现这里是代码实现,下面的m.

2021-03-08 15:41:12 170 1

原创 iOS--数组越界终极解决办法

在项目的开发中,笔者一般遇到的问题就是,数组越界:1. -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array;2. -[__NSArrayM objectAtIndexedSubscript:]: index 0 beyond bounds for empty array;很明显,这两个函数是在数组取值的时候发生的越界情况,在网上搜索了很多大神的文章,也自己总结了一下,下面罗列出两种处理方法:一、为NS...

2020-08-12 11:19:34 3390

原创 iOS实时编译

iOS教你如何像RN一样实时编译一、先看效果图最终效果: 代码在保存之后,立马在模拟器上看到修改后的效果, 避免Command+R重新编译耗费时间的问题; 如果APP页面层级太深的话,传统调试要一步步点进到指定页面,使用该方案直接就能看到效果,所见即所得,????????????修改lab的文字的演示二、背景每次都被我们项目的编译速度整的快没脾气了,一直想着优化项目的编译速度。 想想之前做的RN项目的热部署效果真的很爽,不爽之余想到:他用个杂交品.

2020-08-06 10:31:45 416

原创 iOS【使用MJRefresh上拉加载 回调将会多次调用的问题】

最近 升级Xcode 9 + iOS 11后,发现原本没问题的tableView出现了好多异常。使用MJRefresh上拉加载的时候如果没有更多数据,用上次的数据刷新tableview 然后【self.tableView.mj_footer endRefreshing】后,回调将会多次调用一、头部刷新UI出现了错乱。如上图 tableview已向下偏移

2018-01-11 17:28:36 1115

原创 UIImagePickerController在iOS11访问相册

iOS11来了以后,最近审核被拒绝,原因是:弹出系统权限的时候,必须说出用途。否则会被以Guideline 5.1.2 - Legal - Privacy - Data Use and Sharing拒绝你。很难理解苹果的思想,谁让人家整出了苹果神机,垄断了市场。。。还是不说了,直接说这个问题。我查了资料很难找到直接1.2句代码能解决这个问题的方法,最后还是自己写的提示

2017-12-13 16:00:59 3198 1

原创 IPv6审核已经通过,历经几个星期的经验积累。

继上一篇博客 http://blog.csdn.net/lucky_deng/article/details/70241293 的继续,越来越发现苹果审核很反复无常不同的人审核的结果越来越不一样,有的人运气在IPv4环境下审核通过了,这个网址测试还是有用的,我感觉 http://ipv6-test.com/validate.php 为什么这么说呢?因为我们的域名测试(没有做反向代理之前 );测试结果如下经过服务器人员一天的配置,再测试我们的服务器是这样的我是一个应用过了一个应用一直没过,到今天早

2017-04-26 10:06:53 3278

空空如也

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

TA关注的人

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