更新:这个以前的 Xcode 插件已被重新组织成 Swift 包,以便在其他应用程序中使用。在客户端应用程序中使用Xprobe
产品,在服务器端使用XprobeUI
产品。
XprobePlugin 为您提供了应用程序内部对象的视图,可以详细到 ivars 级别,也可以全局显示主要对象及其连接方式的图表。该显示可以实时动画化,在发送消息时以红色对象突出显示以及消息流动的路径。这是通过执行“扫描”自动完成的,以查找一组种子引用的所有对象、它们引用的对象、那些引用的对象等等,以构建可以在 Xcode 中显示的活动对象列表:
在模拟器中,内存清理器是使用 lldb 从插件内的捆绑包加载的,无需更改应用程序的项目源。要使用该插件,请构建此项目并重新启动 Xcode。应用程序运行后,使用菜单项“Product/Xprobe/Load”加载应用程序内存扫描的初始视图。如果您是插件开发人员,您可以使用“Product/Xprobe/Xcode”来检查 Xcode 应用程序本身的对象。
然后,您可以使用模式过滤应用程序中列出的对象或其方法。如果没有与该模式匹配的对象并且它是一个类名,则会显示该名称。以“+”或“-”为前缀的模式将搜索链接到应用程序的所有类以查找与该模式匹配的方法。可以输入前缀为“0x”的原始指针来检查作为参数传递给跟踪的对象。您还可以输入以“种子”开头的对象“路径”。从您浏览应用程序时记录的路径中,您可以轻松找到返回对象的路径。
如果您安装了injectionforxcode插件,Xprobe将允许您针对选定的实例评估Objective-C或Swift,您有源在运行时记录或修改对象状态的任何方面。
Xprobe.mm 现在可以在发生错误时将您的应用程序快照到独立的 html 文件。这会执行扫描,并记录错误发生时应用程序的状态以供以后分析。可以在此处查看 ReactNative 示例项目“TickTackToe”的示例快照文件。
要拍摄快照,请在您的应用程序中包含 Xprobe.mm 并使用以下调用:
[Xprobe snapshot: @" /path/to/snapshot.html.gz " seeds: @[app delegate, rootViewController]];
如果遇到困难,您可以更改类名称的模式,以便不使用附加的排除:(NSString *)模式参数来捕获。默认值为:
@" ^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK) "
其余功能最容易通过一系列要点来展开:
单击对象的链接可查看其 ivar 内容。
再次单击该链接可关闭详细信息视图。
单击超类链接查看其 ivars
单击 ivar 名称可从应用程序刷新其值
单击 ivar 值以在应用程序中编辑和设置其值
可以查看类的属性、方法和任何协议。
可以搜索方法列表(也可以查找超类方法)
使用“trace”链接开始记录对该实例上的方法的调用。
要查看为某个对象跟踪的所有方法,请单击每个类的“跟踪”。
可以使用正则表达式过滤跟踪输出
子视图链接将递归地显示视图下的子视图树。
当对象是视图时,“渲染”链接将捕获图像。
兄弟链接将显示所有找到的共享该对象类的对象。
通过在搜索字段中键入 Enter 来刷新对象列表以强制进行新的扫描。
按“图表”按钮将打开最重要对象以及从上次扫描中直接链接到它们的任何“套件”对象的摘要视图。
如果对象是视图(响应“子视图”),则该对象表示为正方形。
图形显示需要在计算机上安装“Graphviz/dot”。
单击一个对象可查看其当前内容,如上所述。
可以对要包含的对象应用不同的过滤。
“动画消息”会在对象上留下痕迹,使其在收到消息时显示“红色”。
图表可以导出为 Graphviz 或 .png 格式以供打印。
遗憾的是,目前 Swift 支持受到限制,因为 ivar_getTypeEncoding() 对 ivar 字段返回 NULL,从而阻止它们参与“扫描”。
Xprobe 的工作原理是在模拟器中加载一个包,该包在加载时会连接到 Xcode。应用程序通过实现以下类别来使其种子节点列表为 Xprobe 所知:
@implementation Xprobe (Seeding)
+ ( NSArray *)xprobeSeeds {
UIApplication *app = [UIApplication sharedApplication ];
NSMutableArray *seeds = [ NSMutableArray arrayWithObject: app];
[seeds addObjectsFromArray: [app windows ]];
// support for cocos2d
Class ccDirectorClass = NSClassFromString ( @" CCDirector " );
CCDirector *ccDirector = [ccDirectorClass sharedDirector ];
if ( ccDirector )
[seeds addObject: ccDirector];
return seeds;
}
@end
或者对于 OSX:
+ ( NSArray *)xprobeSeeds {
NSApplication *app = [ NSApplication sharedApplication ];
NSMutableArray *seeds = [[app windows ] mutableCopy ];
if ( app. delegate )
[seeds insertObject: app.delegate atIndex: 0 ];
return seeds;
}
应用程序初始化后,调用 [Xprobe connectTo:"your.ip.address" keepObjects:YES] 连接到 Xcode 内运行的 TCP 服务器。 keepObjects: 参数指定是否保留扫描中找到的对象。这将使 Xprobe 更加可靠,但会影响应用程序中的对象生命周期。之后,调用 [Xprobe search:@""] 从这些对象开始执行初始扫描,寻找根对象。每次调用“search:”或更改对象类过滤器时,都会重新执行扫描。该应用程序需要使用 Xprobe 和 Xtrace 构建。{h,mm}。
在当今这个干净的“强”和“弱”指针时代,如果对象以某种方式对种子可见,那么扫描似乎非常可靠。一些遗留类的行为不佳,并使用“分配”属性,其中可以包含指向已释放对象的指针。为了避免清除这些类的 ivars,Xprobe 有一个排除过滤器,可以在类别中覆盖(带有警告):
static NSString *swiftPrefix = @" _TtC " ;
@implementation Xprobe (ExclusionOverride)
+ ( BOOL )xprobeExclude:( NSString *)className {
static NSRegularExpression *excluded;
if ( !excluded )
excluded = [ NSRegularExpression xsimpleRegexp: @" ^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory) " ];
return [excluded xmatches: className] && ![className hasPrefix: swiftPrefix];
}
@end
这些排除允许 Xprobe 在 Xcode 本身内部干净地工作,如果您是插件开发人员,这会很方便。如需任何建议或反馈,您可以通过 xprobe johnholdsworth.com 联系作者。主要版本将在 Twitter @Injection4Xcode 上发布。
使用 Swift 2.3+,Xprobe 不再能够扫描没有属性的 ivars,即不从 NSObject 继承的类。
Xprobe.{h,mm} - 快照所需的核心 Xprobe 功能 IvarAccess.h - 通过名称访问类 ivars 所需的例程 Xprobe+Service.mm - 连接到 Xcode 的可选交互式服务
版权所有 (c) 2014-5 约翰·霍尔兹沃思。在 Objectice-C 应用程序开发过程中获得下载、修改和任何使用许可,重新分发只能通过公共存储库 github 进行,但包括本版权声明。如需使用您的应用程序进行二进制重新分发,请联系!
此版本包括优秀的 canviz 库的一个非常细微的修改版本,用于在 HTML 画布中渲染“点”文件,该画布受 MIT 许可证的约束。这些更改是将节点的 ID 传递到节点标签标记(第 212 行),反转节点和连接它们的线的渲染(第 406 行)并存储边缘路径,以便可以对它们进行着色(第 66 行和303)在“canviz-0.1/canviz.js”中。
现在,它还包括 CodeMirror JavaScript 编辑器,用于在 MIT 许可证下使用注入来评估代码。
本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有者均不对因本软件或本软件中的使用或其他交易而产生或与之相关的任何索赔、损害或其他责任负责,无论是合同、侵权行为还是其他行为。软件。