iOS从UI内存地址到读取成员变量(oc/swift)
开发调试时,我们发现bug时常首先是从UI显示发现异常,下一步才会去定位UI相关连的数据的。XCode有给我们提供一系列debug工具,但是很多人可能还没有形成一套稳定的调试流程,因此本文尝试解决这个问题,顺便提出一个暴论:UI显示异常问题只需要两个步骤就能完成定位工作的80%:
- 定位异常 UI 组件的内存地址。
- 利用内存地址读取其成员变量。
定位异常UI组件内存地址
查看UI组件内存的方法还是蛮简单的,这里简单介绍。Xcode有提供可视化的UI查看工具:“Debug View Herarchy”,查看右侧辅助栏第四个选项(键盘快捷键cmd+opt+4)。

感兴趣的还可以去了解Lookin、chisel、HMLLDB,不管哪一个,用起来都比那个基佬的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)的更多相关文章
- 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态
一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...
- iOS类别(category)不能添加成员变量但是可以添加属性的问题
类别不需要介绍了把,网上一大堆(利用Objective-C的动态运行时分配机制,可以为现有的类添加新方法,这种为现有的类添加新方法的方式称为类别catagory,他可以为任何类添加新的方法,包括那些没 ...
- 第50 课C++对象模型分析——成员变量(上)
C++对象模型,其实就是C++中的对象在内存中是如何排布的.C++中的对象包含了成员变量和成员函数,其实就是研究C++中的类对象它的成员变量和成员函数在内存中是如何排布的. 回归本质class 是一种 ...
- iOS开发系列-打印内存地址
打印内存地址 基本数据类型 定义一个基本数据类型,会根据变量类型分配对应的内存空间.比如定义一个int类型的变量a. int a = 10; 内存如下 输入变量a在内存中内存地址 NSLog(@&qu ...
- java成员变量和局部变量的初始化和内存中的运行机制
成员变量: 当系统加载类或创建类的实例时,系统会自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值. eyeNum是类属性.name是实例属性 所有person实例访问eyeNu ...
- 从汇编看c++初始化列表初始化成员变量
简略来说,编译器会对初始化列表按照成员变量的声明顺序重新一一排序,安插到构造函数中进行初始化操作,而且这些初始化操作在构造函数里面用户自己定义的任何代码之前. 下面是c++源码: class X { ...
- OC语法2——OC的类,方法,成员变量的创建
类的创建: 与Java不同的是,OC创建一个类需要两个文件(.h和.m文件) 1> xxx.h:声明文件.用于声明成员变量和方法.关键字@interface和@end成对使用. 声明文件只是声明 ...
- 牛客网Java刷题知识点之全局变量(又称成员变量,分为类变量和实例变量)、局部变量、静态变量(又称为类变量)
不多说,直接上干货! 定义类其实就是在定义类中的成员.成员:成员变量<-->属性,成员函数<-->行为. 局部变量在方法内部声明,并且只能在方法内部使用,在外层的方法被调用时被 ...
- 深入理解PHP内核(十四)类的成员变量及方法
原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的. 类的成员方法在PHP中本质是一个函数, ...
- C++中的static 成员变量的一些注意点
C++中的static成员变量主要用来为多个对象共享数据 例: #include <iostream> using namespace std; class Student{ public ...
随机推荐
- [FAQ] 阿里云一口价域名购买之后在哪里看
进入控制台,产品和服务中找到"域名",进去后在左侧菜单有 "已买到的域名". 如图: Link:https://www.cnblogs.com/farwish/ ...
- dotnet 警惕 C# 的 is var 写法
本文将和大家介绍 C# 语言设计里面,我认为比较坑的一个语法.通过 is var 的写法,会让开发者误以为 null 是不被包含的,然而事实是在这里的 var 是被赋予含义的,将被允许 null 通过 ...
- 临时容器ephermeral(20)
一.临时容器ephermeral概述 参考官方文档: https://kubernetes.io/zh/docs/concepts/workloads/pods/ephemeral-container ...
- Mac安装mysql5.7
1.下载文件(访问就直接下载了) http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.10-osx10.10-x86_64.dmg 2.打开下 ...
- SAP集成技术(六)技术、标准和协议
本文链接:https://www.cnblogs.com/hhelibeb/p/17849837.html 内容摘录自<SAP Interface Management Guide>. W ...
- Javascript返回顶部和砸金蛋,跑马灯等游戏代码实现
1. 我们经常写页面的时候会遇到页面很长需要做返回顶部的操作:$("id /class").animate({scrollTop:$('.class').offset().top} ...
- 如何去掉WordPress分类目录url链接中的category,如何处理生成的作者链接
一个新网站需要结合SEO,才能做成一个优秀的网站, ◆◆◆ 关于WordPress的分类目录url中含有category的处理办法: 1,如果是新网站这些设置需要提前做,方便以后做SEO 1.修改固定 ...
- AIRIOT答疑第2期|如何使用物联网平台的数据采集与控制引擎?
任性用! 作为AIRIOT物联网低代码平台的五大核心能力引擎之一,数据采集与控制引擎具备极强的系统集成能力,提供丰富的接口,具备海量工业设备驱动库,分布式采集,稳定性高,实现快速的设备接入.报警. ...
- vue3.4中KeepAlive的一个bug
KeepAlive可以缓存组件,在不使用include时没有任何问题,可以正常缓存. 但是一旦使用了include,如果动态组件中没有导入ref函数,缓存功能就消失了 比如 editcom.vue & ...
- VSCode 圈复杂度插件 CodeMetrics
前言 圈复杂度(Cyclomatic Complexity)是一种代码复杂度的衡量标准.它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测 ...