如何检测外部库是否正在调用[UIDevice currentDevice] uniqueIdentifier]?

9

因此,自从苹果现在拒绝访问UDID的应用程序, 在我们公司目前的项目中,我们需要消除所有调用此属性的API:

[[UIDevice currentDevice] uniqueIdentifier]

我们已经在自己的代码中消除了所有调用,但需要确定我们使用的许多外部库是否正在调用此属性。最可靠的方法是什么来确定库是否在调用此属性?谢谢!

这些外部库是开源的吗? - cubuspl42
大多数库不是开源的。 - Colin Basnett
请查看此答案:https://dev59.com/DmLVa4cB1Zd3GeqPsQWY#9894190 - maroux
检查这个答案,我从苹果得到的提示http://stackoverflow.com/questions/16449182/itunes-app-submission-invalid-binary-issues/16514820#16514820 - Ishara Meegahawala
3个回答

14

除了使用看起来有点不稳定的 otx 之外,另一个选择是在该方法上设置一个符号断点,然后运行应用程序一段时间,看是否命中它。

为该方法配置符号断点的方式如下:

enter image description here

如果您命中了该断点,可以通过打开调试器控制台并输入bt来找出是谁调用了它。 在这种情况下,调用来自于我的application:didFinishLaunchingWithOptions:, 但无论谁调用它都可以使用此方法。

(lldb) bt
* thread #1: tid = 0x1c03, 0x001f4690 UIKit`-[UIDevice uniqueIdentifier], stop reason = breakpoint 1.1
frame #0: 0x001f4690 UIKit`-[UIDevice uniqueIdentifier]
frame #1: 0x0000212e MyApp`-[AppDelegate application:didFinishLaunchingWithOptions:](self=0x0747fcb0, _cmd=0x005aec21, application=0x08366300, launchOptions=0x00000000) + 702 at AppDelegate.m:37
frame #2: 0x00015157 UIKit`-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 266
frame #3: 0x00015747 UIKit`-[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1248
frame #4: 0x0001694b UIKit`-[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 805
frame #5: 0x00027cb5 UIKit`-[UIApplication handleEvent:withNewEvent:] + 1022
frame #6: 0x00028beb UIKit`-[UIApplication sendEvent:] + 85
frame #7: 0x0001a698 UIKit`_UIApplicationHandleEvent + 9874
frame #8: 0x01f01df9 GraphicsServices`_PurpleEventCallback + 339
frame #9: 0x01f01ad0 GraphicsServices`PurpleEventCallback + 46
frame #10: 0x01f1bbf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #11: 0x01f1b962 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #12: 0x01f4cbb6 CoreFoundation`__CFRunLoopRun + 2118
frame #13: 0x01f4bf44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #14: 0x01f4be1b CoreFoundation`CFRunLoopRunInMode + 123
frame #15: 0x0001617a UIKit`-[UIApplication _run] + 774
frame #16: 0x00017ffc UIKit`UIApplicationMain + 1211
frame #17: 0x00001d42 MyApp`main(argc=1, argv=0xbffff3f8) + 130 at main.m:16

1
谢谢,非常有效!我想唯一的问题是,它只能在实际调用函数时捕获到它,而不能在它有潜在调用时捕获到它。 - Colin Basnett
非常感谢您!这帮助我们找到了一个遗漏的库,节省了可能需要一周的时间!+1 - Karthik T

3

对Quinn的回答进行扩展:

  • strings列出编译对象或库中出现顺序为每个类的所有符号。如果在输出中看到uniqueIdentifier,那么可能他们正在调用该名称的某个其他方法。但是,如果您在输出中立即看到currentDevice,后面紧跟着uniqueIdentifier,那么他们几乎肯定正在调用[[UIDevice currentDevice] uniqueIdentifier]。如果库在文件中较早地调用了currentDevice,那么这两行可能不是连续的。
  • otool -ov 列出库中的所有类、方法和导入项。如果它列出了uniqueIdentifier,那么很可能表明该库正在定义自己的带有该名称的方法。查看上下文中的参考。在每个类的底部,您会看到一个类似于Contents of (__DATA,__objc_classrefs) section的部分,其中列出了导入项。如果在引用uniqueIdentifier的类的导入项中列出了_OBJC_CLASS_$_UIDevice,那么该类很可能正在调用-[UIDevice uniqueIdentifier]
  • nm的输出与otool类似。具体来说,它不会显示对uniqueIdentifier的调用,但它会向您显示哪些类导入了UIDevice

2
确定一个闭源库是否在调用某个方法可能会比较困难,但有一些方法可以帮助你判断它们可能会调用:

  • 使用strings命令查看库文件中是否出现了“uniqueIdentifier”字样,无论它的使用方式是什么:

    $ strings libFoo.a | grep uniqueIdentifier

  • 使用nmotool(参见此答案

  • 使用otx(参见此答案

这些方法可以帮助你找出设置断点时可能会错过的潜在调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接