之前对lldb调试器了解比较少,平时主要用来打印日志和暂定时用鼠标查看属性数据以及使用p po一些简单的命令语句。

今天看了一些关于lldb的文章,顿时觉得之前对它了解太少了,原来它还有那么多的功能。

好记性不如烂笔头,我把方便易用的命令记录下来,方便以后查看。

一、ldb的语法结构

lldb的语法结构如下:
<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]
翻译一下:
<命令> [<子命令> [<子命令>...]] <命令操作> [命令选项] [参数 [参数..]]
一个命令对象为跟随其的子命令对象创建一个上下文,子命令又为其子命令创建一个上下文,依此类推.

举个例子,假设我们给main方法设置一个断点,我们使用下面的命令:

breakpoint set -n main
这个命令对应到上面的语法就是:

command: breakpoint 表示断点命令
action: set 表示对命令怎样的操作
option: -n 表示根据方法name设置断点(--name)
arguement: 方法名mian 表示参数mian

二、原始(raw)命令
lldb支持不带命令选项(options)的原始(raw)命令,原始命令会将命令后面的所有东西当做参数(arguement)传递。
不过很多原始命令也可以带命令选项,当你使用命令选项的时候,需要在命令选项后面加--区分命令选项和参数。

expression命令 就是一个原始命令,举例如下:
1.打印一个变量
(lldb) expression count
(int) $2 = 4
2.打印一个对象,打印对象时需要用-O命令选项,选项后面是“--”分隔符,后面接着 参数
(lldb) expression -O -- self
<ViewController: 0x7f9000f17660>

三、唯一匹配原则
lldb的命令遵循唯一匹配原则,举例如下
(lldb) breakpoint set -n touchesBegan:withEvent:
(lldb) bre s -n touchesBegan:withEvent:
这两个命令的效果是一样的,因为根据字母"bre"匹配到的命令只有“breakpoint”,根据字母"s"匹配到的命令操作只有“set”

四、lldb常用命令
1.expression
expression命令的作用是执行一个表达式,并将表达式返回的结果输出。expression的完整语法是这样的:
expression <cmd-options> -- <expr>
对应的例子如下:
(lldb) expression -O -- self
<ViewController: 0x7f9000f17660>
expression <命令选项> “--”分隔符 执行的参数或表达式

expression是lldb里面最重要的命令。他能实现2个非常重要的功能。
a.执行表达式。
在程序暂停时,可以通过lldb调试器直接修改页面属性,而不需要重新运行程序
// 改变颜色
(lldb) expression -- self.view.backgroundColor = [UIColor redColor]
// 刷新界面
(lldb) expression -- (void)[CATransaction flush]
b.输出返回值
(lldb) expression -- self.view
(UIView *) $1 = 0x00007fe322c18a10

2.p 、print 、 call 命令
p、print、call。这三个命令其实都是expression --的别名(--表示不再接受命令选项)是对expression --的一层封装
它们同样拥有expression的两项重要的功能,a.执行表达式,b.输出返回值
(lldb) p self.count
(CGFloat) $1 = 30
(lldb) print self.count
(CGFloat) $1 = 30
(lldb) call self.count
(CGFloat) $1 = 30
(lldb) expression -- self.count
(CGFloat) $2 = 30

3.po
在OC里所有的对象都是用指针表示的,所以一般用p、print、call、expression --打印的时候,打印出来的是对象的指针,而不是对象本身。如果我们想打印对象。我们需要使用命令选项:-O。为了更方便的使用,lldb为expression -O --定义了一个别名:po
举例如下:
(lldb) p self
(SingletonViewController *) $3 = 0x00007fda32a8f9d0
(lldb) po self
<SingletonViewController: 0x7fda32a8f9d0>
更多expression 的学习可以用 help expression获取,然后细细研究

4.thread
A. thread backtrace 、 bt
在程序暂停时,若要获取此时线程的堆栈信息,可以通过thread backtrace 命令获取,该命令的语法如下:
thread backtrace [-c <count>] [-s <frame-index>] [-e <boolean>]
-c:设置打印堆栈的帧数(frame)
-s:设置从哪个帧(frame)开始打印
-e:是否显示额外的回溯
实际上这些命令选项我们一般不需要使用。当程序暂定后,只需要调用thread backtrace命令就能将常用的信息打印出来.
bt命令 同 thread backtrace 命令一样,举例如下:
(lldb) thread backtrace
* thread #1: tid = 0x3ae2, 0x0000000106ccc5a6 MyTestWorkProduct`-[SingletonViewController touchesBegan:withEvent:](self=0x00007fda32a8f9d0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00007fda307057b0) + 86 at SingletonViewController.m:61, queue = 'com.apple.main-thread', stop reason = breakpoint 4.1
* frame #0: 0x0000000106ccc5a6 MyTestWorkProduct`-[SingletonViewController touchesBegan:withEvent:](self=0x00007fda32a8f9d0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00007fda307057b0) + 86 at SingletonViewController.m:61
frame #1: 0x0000000108972227 UIKit`forwardTouchMethod + 349
frame #2: 0x00000001089720b9 UIKit`-[UIResponder touchesBegan:withEvent:] + 49
frame #3: 0x00000001087d3790 UIKit`-[UIWindow _sendTouchesForEvent:] + 308
frame #4: 0x00000001087d46d4 UIKit`-[UIWindow sendEvent:] + 865
frame #5: 0x000000010877fdc6 UIKit`-[UIApplication sendEvent:] + 263
frame #6: 0x0000000106c15d73 MyTestWorkProduct`-[UIApplication(self=<unavailable>, _cmd=<unavailable>, event=<unavailable>) btg_swizzleSendEvent:] + 72 at UIApplication+BTGMethodSwizzler.m:27 [opt]
frame #7: 0x0000000108759553 UIKit`_UIApplicationHandleEventQueue + 6660
frame #8: 0x000000010b32f301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #9: 0x000000010b32522c CoreFoundation`__CFRunLoopDoSources0 + 556
frame #10: 0x000000010b3246e3 CoreFoundation`__CFRunLoopRun + 867
frame #11: 0x000000010b3240f8 CoreFoundation`CFRunLoopRunSpecific + 488
frame #12: 0x000000010da06ad2 GraphicsServices`GSEventRunModal + 161
frame #13: 0x000000010875ef09 UIKit`UIApplicationMain + 171
frame #14: 0x0000000106d4204a MyTestWorkProduct`main(argc=1, argv=0x00007fff590025d8) + 138 at main.m:16
frame #15: 0x000000010c3c592d libdyld.dylib`start + 1
frame #16: 0x000000010c3c592d libdyld.dylib`start + 1
(lldb) bt
* thread #1: tid = 0x3ae2, 0x0000000106ccc5a6 MyTestWorkProduct`-[SingletonViewController touchesBegan:withEvent:](self=0x00007fda32a8f9d0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00007fda307057b0) + 86 at SingletonViewController.m:61, queue = 'com.apple.main-thread', stop reason = breakpoint 4.1
* frame #0: 0x0000000106ccc5a6 MyTestWorkProduct`-[SingletonViewController touchesBegan:withEvent:](self=0x00007fda32a8f9d0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00007fda307057b0) + 86 at SingletonViewController.m:61
frame #1: 0x0000000108972227 UIKit`forwardTouchMethod + 349
frame #2: 0x00000001089720b9 UIKit`-[UIResponder touchesBegan:withEvent:] + 49
frame #3: 0x00000001087d3790 UIKit`-[UIWindow _sendTouchesForEvent:] + 308
frame #4: 0x00000001087d46d4 UIKit`-[UIWindow sendEvent:] + 865
frame #5: 0x000000010877fdc6 UIKit`-[UIApplication sendEvent:] + 263
frame #6: 0x0000000106c15d73 MyTestWorkProduct`-[UIApplication(self=<unavailable>, _cmd=<unavailable>, event=<unavailable>) btg_swizzleSendEvent:] + 72 at UIApplication+BTGMethodSwizzler.m:27 [opt]
frame #7: 0x0000000108759553 UIKit`_UIApplicationHandleEventQueue + 6660
frame #8: 0x000000010b32f301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #9: 0x000000010b32522c CoreFoundation`__CFRunLoopDoSources0 + 556
frame #10: 0x000000010b3246e3 CoreFoundation`__CFRunLoopRun + 867
frame #11: 0x000000010b3240f8 CoreFoundation`CFRunLoopRunSpecific + 488
frame #12: 0x000000010da06ad2 GraphicsServices`GSEventRunModal + 161
frame #13: 0x000000010875ef09 UIKit`UIApplicationMain + 171
frame #14: 0x0000000106d4204a MyTestWorkProduct`main(argc=1, argv=0x00007fff590025d8) + 138 at main.m:16
frame #15: 0x000000010c3c592d libdyld.dylib`start + 1
frame #16: 0x000000010c3c592d libdyld.dylib`start + 1

B. thread return
Debug的时候,有时候会因为各种原因,不想让代码沿着方法继续执行了。要么直接返回,要么带上一个值直接返回。
语法为:thread return [<expr>]
举例如下:
(lldb) thread return
(lldb) thread return NO

C. c 、n 、s 、 finish
在lldb调试器的做上角有个暂停按钮,右边三个顺序为:单步执行、进入方法、从当前方法返回到上一层frame
这三个按钮平时都是手动点击进行调试,在lldb调试器中,也有相应的命令可以操作
分别说明如下:
c/ continue/ thread continue: 这三个命令效果都表示程序继续运行
n/ next/ thread step-over: 这三个命令效果都表示单步运行
s/ step/ thread step-in: 这三个命令效果都表示进入某个方法
finish/ step-out: 这两个命令效果都表示直接走完当前方法,返回到上层frame

D. thread其他不常用的命令
thread list: 列出所有的线程
thread select: 选择某个线程
thread info: 输出当前线程的信息
其他更多的命令可以使用命令help thread学习

5. frame(帧)
在第4项thread命令中,有个thread backtrace 命令,该命令会打印出当前线程的堆栈信息,其中里面的每一条就是一帧(frame)
举例如下:
frame #0: 0x0000000106ccc5a6 MyTestWorkProduct`-[SingletonViewController touchesBegan:withEvent:](self=0x00007fda32a8f9d0, _cmd="touchesBegan:withEvent:", touches=1 element, event=0x00007fda307057b0) + 86 at SingletonViewController.m:61
frame #1: 0x0000000108972227 UIKit`forwardTouchMethod + 349
frame #2: 0x00000001089720b9 UIKit`-[UIResponder touchesBegan:withEvent:] + 49

A. frame variable 打印当前frame中的变量信息
举例如下:
(lldb) frame variable
(SingletonViewController *) self = 0x00007fda32a8f9d0
(SEL) _cmd = "touchesBegan:withEvent:"
(__NSSetM *) touches = 0x00007fda32ad6a70 1 element
(UITouchesEvent *) event = 0x00007fda307057b0
(NSInteger) count1 = 10
(NSInteger) count2 = 20
(lldb) frame variable self->_count
(CGFloat) self->_count = 30

B. frame其他不常用命令
frame info: 查看当前frame的信息
frame select: 选择某个frame

6. breakpoint 断点命令,lldb中的断点命令非常强大
A. breakpoint set 断点设置,用于断点设置的方式有多种 分别如下:
使用-n根据方法名设置断点:
给所有类中的viewWillAppear:设置一个断点:
(lldb) breakpoint set -n viewWillAppear:
Breakpoint 13: 33 locations.
使用-f指定文件
只需要给ViewController.m文件中的viewDidLoad设置断点:
(lldb) breakpoint set -f ViewController.m -n viewDidLoad
Breakpoint 22: where = TLLDB`-[ViewController viewDidLoad] + 20 at ViewController.m:22, address = 0x000000010272a6f4
这里需要注意,如果方法未写在文件中(比如写在category文件中,或者父类文件中),指定文件之后,将无法给这个方法设置断点。
使用-l指定文件某一行设置断点
给ViewController.m第38行设置断点
(lldb) breakpoint set -f ViewController.m -l 38
Breakpoint 23: where = TLLDB`-[ViewController text:] + 37 at ViewController.m:38, address = 0x000000010272a7d5
使用-c设置条件断点
text:方法接受一个ret的参数,我们想让ret == YES的时候程序中断:
(lldb) breakpoint set -n text: -c ret == YES
Breakpoint 7: where = TLLDB`-[ViewController text:] + 30 at ViewController.m:37, address = 0x0000000105ef37ce
使用-o设置单次断点
如果刚刚那个断点我们只想让他中断一次:
(lldb) breakpoint set -n text: -o
'breakpoint 3': where = TLLDB`-[ViewController text:] + 30 at ViewController.m:37, address = 0x000000010b6f97ce

B. breakpoint command 命令 子命令
在程序走到断点后,有时候需要执行一些命令,而这些命令是可以操作的。我们可以为断点添加,删除命令
B1. breakpoint command add 添加命令
(lldb) breakpoint command add -o "po self" 3
解释:为断点号为:3 的断点添加一条命令。 -o完整写法是--one-liner。
(lldb) breakpoint command add 3
Enter your debugger command(s). Type 'DONE' to end.
> frame variable
> continue
> DONE
解释:为断点ID为:3的断点添加多个命令,这些命令以“ DONE”作为结束符。
B2. breakpoint command list 3
获取断点ID为:3的 断点的命令列表
B3. breakpoint command delete 3
删除断点ID为:3的 断点的所有命令

C. breakpoint list
获取工程中所有断点的列表

D. breakpoint disable/enable
断点的失效/生效
举例如下:
(lldb) breakpoint disable 1
1 breakpoints disabled.
(lldb) breakpoint disable 1
1 breakpoints disabled.

F. breakpoint delete
删除断点
(lldb) breakpoint delete 1
删除断点ID为:1的断点
(lldb) breakpoint delete
About to delete all breakpoints, do you want to do that?: [Y/n] y
All breakpoints removed. (1 breakpoint)
删除工程中所有的断点
(lldb) breakpoint delete -f
All breakpoints removed. (1 breakpoint)
强制所有的断点,忽略提示

7. watchpoint
breakpoint有一个孪生兄弟watchpoint。如果说breakpoint是对方法生效的断点,watchpoint就是对地址生效的断点
在开发过程中,平时我们简称一个属性的变化通常是使用属性的set方法,如果属性没有经过set方法,是直接通过self->属性直接修改的话,用set方法就不行了,此时可以通过watchpoint命令监听属性的内存地址,一旦address的内容被修改,程序就会自动断开。
A. watchpoint set
设置观测点
watchpoint set variable <变量参数> 为变量设置观测点
(lldb) watchpoint set variable self->_string
Watchpoint created: Watchpoint 1: addr = 0x7fcf3959c418 size = 8 state = enabled type = w
watchpoint spec = 'self->_string'
new value: 0x0000000000000000
watchpoint set expression <变量地址参数> 为变量地址设置观测点
(lldb) p &_model
(Modek **) $3 = 0x00007fe0dbf23280
(lldb) watchpoint set expression 0x00007fe0dbf23280
Watchpoint created: Watchpoint 1: addr = 0x7fe0dbf23280 size = 8 state = enabled type = w
new value: 0

B. watchpoint command
跟breakpoint类似,在watchpoint中也可以添加命令

C. watchpoint command add
为观测点添加命令
watchpoint command add -o 'po self' 1
为ID为:1的观测点添加一条 命令
(lldb) watchpoint command add 1
Enter your debugger command(s). Type 'DONE' to end.
> po self
> continue
> DONE
为ID为:1的观测点添加多条命令

D. watchpoint command list
查询观测点命令列表
(lldb) watchpoint command list 1
查询观测点ID为:1的观测点,命令列表

F. watchpoint command delete
(lldb) watchpoint command delete 1
删除观测点ID为:1的观测点的命令列表

E. watchpoint list
查询工程中的所有观测点列表

F. watchpoint disable
(lldb) watchpoint disable 1
设置观测点ID为:1的观测点为失效

G. watchpoint enable
(lldb) watchpoint enable 1
设置观测点ID为:1的观测点为生效

H. watchpoint delete
(lldb) watchpoint delete 1
删除观测点ID为:1的观测点
(lldb) watchpoint delete
About to delete all watchpoints, do you want to do that?: [Y/n] y
All watchpoints removed. (2 watchpoints)
删除工程中的观测点

8. target 根据参数 打印出参数信息对应在项目文件中的位置
对于target这个命令,平时用的最多的是target modules lookup。由于LLDB给target modules取了个别名image,所以这个命令我们又可以写成image lookup。
A.image lookup --address 根据所给的内存地址,找到符号所在项目文件中的位置。简写为image lookup -a
当发生一个崩溃时,可以通过打印内存地址的方式定位到崩溃发生的地方。
举例如下:
2017-04-14 21:49:30.784 MyTestWorkProduct[955:18657] -[__NSDictionaryM addObject:]: unrecognized selector sent to instance 0x7fc50b0e4e70
libc++abi.dylib: terminate_handler unexpectedly threw an exception
(lldb) image lookup -a 0x7fc50b0e4e70
B. image lookup --name 如果想查找一个方法或符号的位置,可通过此命令查找。 简写:image lookup -n
举例如下:
lldb) image lookup -n didReceiveMemoryWarning
26 matches found in /Users/xuyefeng/Library/Developer/Xcode/DerivedData/MyTestWorkProduct-etxrcvqebgprfcfjyibavnioxbey/Build/Products/Debug-iphonesimulator/MyTestWorkProduct.app/MyTestWorkProduct:
Address: MyTestWorkProduct[0x000000010000b742] (MyTestWorkProduct.__TEXT.__text + 40370)
Summary: MyTestWorkProduct`-[BTGBaseViewController didReceiveMemoryWarning] at BTGBaseViewController.m:71 Address: MyTestWorkProduct[0x000000010005de80] (MyTestWorkProduct.__TEXT.__text + 378096)
Summary: MyTestWorkProduct`-[ModelDictionaryTransferVC didReceiveMemoryWarning] at ModelDictionaryTransferVC.m:22 Address: MyTestWorkProduct[0x000000010005df00] (MyTestWorkProduct.__TEXT.__text + 378224)
Summary: MyTestWorkProduct`-[ViewController didReceiveMemoryWarning] at ViewController.m:23 Address: MyTestWorkProduct[0x0000000100061510] (MyTestWorkProduct.__TEXT.__text + 392064)
C. image lookup --type 如果想查找一个类的信息可以用这个命令。简写为image lookup -t
举例如下:
(lldb) image lookup -t Person
Best match found in /Users/xuyefeng/Library/Developer/Xcode/DerivedData/MyTestWorkProduct-etxrcvqebgprfcfjyibavnioxbey/Build/Products/Debug-iphonesimulator/MyTestWorkProduct.app/MyTestWorkProduct:
id = {0x000d796a}, name = "Person", byte-size = 40, decl = Person.h:13, compiler_type = "@interface Person : NSObject{
NSString * _name;
NSString * _adress;
NSNumber * _age;
NSInteger _ID;
}
@property ( getter = name,setter = setName:,readwrite,nonatomic ) NSString * name;
@property ( getter = adress,setter = setAdress:,readwrite,nonatomic ) NSString * adress;
@property ( getter = age,setter = setAge:,readwrite,nonatomic ) NSNumber * age;
@property ( getter = ID,setter = setID:,assign,readwrite,nonatomic ) NSInteger ID;
@end"

D. target stop-hook ,target stop-hook命令就是让你可以在每次stop的时候去执行一些命令
target stop-hook add 、 display 添加命令的方式。
举例如下:
(lldb) target stop-hook add -o "frame variable"
Stop hook #4 added.
注释:-o的全称是--one-liner

F. target stop-hook list
获取全部命令列表
E. target stop-hook delete & undisplay
删除列表
G. target stop-hook disable/enable
使命令失效

9. Extension
在调试器中输入 e @import UIKit 可以打印出view的frame
举例如下:
(lldb) e @import UIKit
(lldb) po self.view.frame
(origin = (x = 0, y = 0), size = (width = 375, height = 667))

10. 更多
更多命令可以使用help 进行学习
apropos 命令可以模糊搜索命令关键字。

参考来源:

小笨狼与LLDB的故事:http://www.jianshu.com/p/e89af3e9a8d7

学习笔记之--认识Xcode中的重要成员:lldb调试器的更多相关文章

  1. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  2. [C#] 类型学习笔记一:CLR中的类型,装箱和拆箱

    在学习.NET的时候,因为一些疑问,让我打算把.NET的类型篇做一个总结.总结以三篇博文的形式呈现. 这篇博文,作为三篇博文的第一篇,主要探讨了.NET Framework中的基本类型,以及这些类型一 ...

  3. [原创]java WEB学习笔记39:EL中的运算符号(算术运算符,关系运算符,逻辑运算符,empty运算符,条件运算符,括号运算符)

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. [原创]java WEB学习笔记38:EL 中的 11个 隐含对象 详解

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  5. [原创]java WEB学习笔记05:Servlet中的ServletConfig对象

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  7. Python学习笔记之从文件中读取数据

    10-1 Python 学习笔记:在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的Python 知识,其中每一行都以“In Python you can”打头.将这个文件命名为learnin ...

  8. Docker学习笔记之-在CentOS中安装Docker

    上一节演示了如何 通过Xshell连接CentOS服务,链接:Docker学习笔记之-通过Xshell连接 CentOS服务 本节将演示 如何在CentOS中安装 Docker 第一步:更新系统包到最 ...

  9. Java泛型学习笔记 - (七)浅析泛型中通配符的使用

    一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...

随机推荐

  1. 在Centos 7 上面 安装MySQL 5.7 简录

    In a web browser, visit mysql.com page: https://dev.mysql.com/downloads/repo/yum/ Locate the desired ...

  2. 查看linux ssh服务信息及运行状态

    关于ssh服务端配置有不少文章,例如 linux下ssh服务配置,这里仅列举出一些查看ssh服务相关信息的常用命令. rpm -qa | grep ssh 可以看到系统中ssh安装包 rpm -ql ...

  3. 前台通过form表单向Django后台传输数据,Django处理后返回给前台

    摘要:Django前后台数据传递 通过action将数据传输给apitest这个地址,使用get方法传递,此处需要传递name="request_method"的下拉列表值和nam ...

  4. Eclipse搭建Android开发环境(安装ADT,Android4.4.2)

    1.检查是否安装JDK, 如果没安装请下载安装 JDK官网http://www.Oracle.com/technetwork/Java/javase/downloads/index.html 2.下载 ...

  5. “全栈2019”Java第九章:解释第一个程序

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. BFC概念和作用,触发条件

    1.概念,全称是block format context,块级格式化上下文 2.触发条件 根元素 float属性不为none position为absolute或fixed display为inlin ...

  7. js中的substr和substring区别

    js中的substr和substring区别 Substring: 该方法可以有一个参数也可以有两个参数. (1)  一个参数: 示例: var str=“Olive”: str.substring( ...

  8. 原始MAC地址

    D8CB8AD97D47

  9. acl权限使用

    1.acl的设置技巧 *setfacl 用法: setfactl [-bkRd] [{-m|-x} acl参数] 目标文件名 -m:设置后续的acl参数给文件使用,不可与-x合用 -x:删除后续的ac ...

  10. element-ui多层嵌套表格数据删除

    很多表格都要一个移除的功能,所谓移除,就是前端把表格的数据删除,普通的表格删除很简单,调用数据的删除方法就行.但是当表格是多层的嵌套类型时,就不能再使用普通的删除方法了.下面介绍一种自己在项目中用的方 ...