开发调试时,我们发现bug时常首先是从UI显示发现异常,下一步才会去定位UI相关连的数据的。XCode有给我们提供一系列debug工具,但是很多人可能还没有形成一套稳定的调试流程,因此本文尝试解决这个问题,顺便提出一个暴论:UI显示异常问题只需要两个步骤就能完成定位工作的80%:

  1. 定位异常 UI 组件的内存地址。
  2. 利用内存地址读取其成员变量。

定位异常UI组件内存地址

查看UI组件内存的方法还是蛮简单的,这里简单介绍。Xcode有提供可视化的UI查看工具:“Debug View Herarchy”,查看右侧辅助栏第四个选项(键盘快捷键cmd+opt+4)。

感兴趣的还可以去了解LookinchiselHMLLDB,不管哪一个,用起来都比那个基佬的Xcode稳定多了(阴阳怪气)。

读取成员变量

这里提出的解决方案是利用LLDB读取,当然二者使用上是存在差异的。

oc篇

暂停程序(cmd+ctrl+y)之后,拿到内存地址,然后:

// 内存地址为0x126708060
po ((ViewController *)(0x126708060)).ocString
// hello world

如果想读取多个变量,可以缩写:

// 内存地址为0x126708060
expr ViewController *$ocPage = (ViewController *)(0x126708060) po $ocPage.ocString
//hello world
po $ocPage.view
//<UIView: 0x13750b930; frame = (0 0; 390 844); autoresize = W+H; backgroundColor = <UIDynamicSystemColor: 0x600001b5b080; name = systemBackgroundColor>; layer = <CALayer: 0x600000e761a0>>

如果是用chisel的话,可以用一个指令打印所有的成员变量

// 内存地址为0x126708060
po pinternals 0x126708060
/*
(ViewController) $7 = {
UIViewController = {
UIResponder = {
NSObject = {
isa = ViewController
}
}
_overrideTransitioningDelegate = nil
_view = 0x000000013750b930
...
_ocString = 0x0000000100eac060 @"hello world"
}
*/

swift篇

暂停程序(cmd+ctrl+y)之后,拿到内存地址,接下来要做的则十分重要,你需要先输入类似于引用的指令(在这里踩坑踩到头皮发麻):

//避免出现报错 error: <user expression 2>:1:1: unknown type name 'let'
settings set target.language swift //避免出现报错 error: <EXPR>:3:43: error: cannot find 'xxxx' in scope
expr import xxxx
//样例中则是 expr import HelloSwift

之后的和oc类似,只是语法比较贴近swift的格式:

// 内存地址0x125e0aae0,类型为HelloSwift.ViewController
expr let $swiftVc = unsafeBitCast(0x125e0aae0, to: HelloSwift.ViewController.self)
po $swiftVc.swiftString
//"Mr_Yu4"

总结

快速定位异常的道路上需要做的工作依然还有很多,lldb会是解决这个问题的重要工具,但是这个工具的学习曲线十分陡峭,所以平时没事的时候,记得在lldb里面多执行这个指令:

help
/*
Debugger commands:
apropos -- List debugger commands related to a word or subject.
breakpoint -- Commands for operating on breakpoints (see 'help b' for
shorthand.)
....
*/

iOS从UI内存地址到读取成员变量(oc/swift)的更多相关文章

  1. 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态

    一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...

  2. iOS类别(category)不能添加成员变量但是可以添加属性的问题

    类别不需要介绍了把,网上一大堆(利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为任何类添加新的方法,包括那些没 ...

  3. 第50 课C++对象模型分析——成员变量(上)

    C++对象模型,其实就是C++中的对象在内存中是如何排布的.C++中的对象包含了成员变量和成员函数,其实就是研究C++中的类对象它的成员变量和成员函数在内存中是如何排布的. 回归本质class 是一种 ...

  4. iOS开发系列-打印内存地址

    打印内存地址 基本数据类型 定义一个基本数据类型,会根据变量类型分配对应的内存空间.比如定义一个int类型的变量a. int a = 10; 内存如下 输入变量a在内存中内存地址 NSLog(@&qu ...

  5. java成员变量和局部变量的初始化和内存中的运行机制

    成员变量: 当系统加载类或创建类的实例时,系统会自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值. eyeNum是类属性.name是实例属性 所有person实例访问eyeNu ...

  6. 从汇编看c++初始化列表初始化成员变量

    简略来说,编译器会对初始化列表按照成员变量的声明顺序重新一一排序,安插到构造函数中进行初始化操作,而且这些初始化操作在构造函数里面用户自己定义的任何代码之前. 下面是c++源码: class X { ...

  7. OC语法2——OC的类,方法,成员变量的创建

    类的创建: 与Java不同的是,OC创建一个类需要两个文件(.h和.m文件) 1> xxx.h:声明文件.用于声明成员变量和方法.关键字@interface和@end成对使用. 声明文件只是声明 ...

  8. 牛客网Java刷题知识点之全局变量(又称成员变量,分为类变量和实例变量)、局部变量、静态变量(又称为类变量)

    不多说,直接上干货! 定义类其实就是在定义类中的成员.成员:成员变量<-->属性,成员函数<-->行为. 局部变量在方法内部声明,并且只能在方法内部使用,在外层的方法被调用时被 ...

  9. 深入理解PHP内核(十四)类的成员变量及方法

    原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的. 类的成员方法在PHP中本质是一个函数, ...

  10. C++中的static 成员变量的一些注意点

    C++中的static成员变量主要用来为多个对象共享数据 例: #include <iostream> using namespace std; class Student{ public ...

随机推荐

  1. Mysql带条件取多条随机记录

    有个文章段落表part,有两种类型的段落,即part_type取1或2,要从表中随机取多条任意类型的段落,比如3条. 方法一 ORDER BY后接RAND() select * from part w ...

  2. 数据表删除DROP TRUNCATE DELETE区别

    总的来说,DROP 用于删除整个数据库对象(表结构和数据全部删除),DELETE 用于删除表中的数据,而 TRUNCATE 也是删除表中的数据,但比 DELETE 更快,且无法指定条件删除.根据需求, ...

  3. 11.17~11.18暨noip2023游寄

    11.17 我们DZ不负众望又干了点nt事,但是为了按时间顺序记叙,所以说放到最后再讲 上午 平常的起床+吃饭,然后就发手机啥的,坐大巴去德州东再坐会高铁去秦皇岛,这些简单记一下就行了 重点来了 先拜 ...

  4. Steam中将XBox手柄默认布局改为任天堂手柄布局的方法

    1. 在Steam菜单栏找到"查看",选择大屏幕模式. 2. 进入大屏幕模式后,在菜单界面找到"设置". 3. 在设置界面找到"控制器",选 ...

  5. 零知识证明: Tornado Cash 项目学习

    前言 最近在了解零知识证明方面的内容,这方面的内容确实不好入门也不好掌握,在了解了一些基础的概念以后,决定选择一个应用了零知识证明的项目来进行进一步的学习.最终选择了 Tornado Cash 这个项 ...

  6. synchronized原理-字节码分析、对象内存结构、锁升级过程、Monitor

    本文分析的问题: synchronized 字节码文件分析之 monitorenter.monitorexit 指令 为什么任何一个Java对象都可以成为一把锁? 对象的内存结构 锁升级过程 Moni ...

  7. C语言:++ --优先级的深入理解

    #include <stdio.h> int main() { int num = 11; int result = ++num > 11 && --num < ...

  8. C语言:如何实现在txt文件中删除超链接、统计单词数量、生成单词列表 (文本流操作并解决乱码)

    1.首先读取原文件内容文本流(包含中英文) 2.删除超链接 3.统计单词数量 4.去除重复单词 读取文件需要自己在文本笔记中保存一个网页,保存为txt文件 注意的是,在这个代码实现过程中,我学到的是如 ...

  9. saltstack web 平台开发

    运维平台参考: https://wrapbootstrap.com/

  10. 详解 XSS 攻击原理

    更多优质博文请关注:听到微笑的博客 跨站脚本攻击(Cross Site Scripting)本来的缩写为CSS,为了与层叠样式表(Cascading Style Sheets,CSS)的缩写进行区分, ...