如何检测是否有任何外部库正在调用 uniqueIdentifier]?

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

[[UIDevice currentDevice] uniqueIdentifier] 

我们已经消除了我们自己代码中的所有调用,但是需要确保我们使用的许多外部库不会调用此属性。

什么是最可靠的方法来确定一个图书馆是否要求这个属性?

先谢谢你!

除了使用otx (似乎已经变得片状)之外,一种select是在该方法上设置一个符号断点,然后运行该应用程序一段时间,看看是否打了它。

configuration该方法的符号断点如下所示:

在这里输入图像说明

如果你碰到这个断点,你可以通过打开debugging器控制台并inputbt来找出是谁调用的。 在这种情况下,调用来自我的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 

为了扩大Quinn的答案:

  • strings按照每个类的第一次出现的顺序列出编译对象或库中的所有符号。 如果您在输出中看到uniqueIdentifier ,则可能是他们正在调用其他名称的方法。 但是,如果您在输出中看到currentDevice后紧跟着uniqueIdentifier ,那么他们几乎肯定会调用[[UIDevice currentDevice] uniqueIdentifier] 。 如果库在文件的前面调用currentDevice ,那么这两行就可能不是顺序的。
  • otool -ov列出库中的所有类,方法和导入。 如果列出了uniqueIdentifier ,那么可能意味着库正在使用该名称定义自己的方法。 看看上下文中的参考。 在每个类的底部,您将看到一个像Contents of (__DATA,__objc_classrefs) section ,其中列出了导入。 如果在您引用_OBJC_CLASS_$_UIDevice的类的导入中列出了_OBJC_CLASS_$_UIDevice ,那么类很有可能正在调用-[UIDevice uniqueIdentifier]
  • nm的输出与otool类似。 具体来说,它不会显示你对uniqueIdentifier调用,但它会告诉你什么类导入UIDevice

可靠地确定一个闭源库是否实际调用一个方法可能是很困难的,但是有一些方法可以看出它们是否可能是:

  • 使用string查看库中是否出现“uniqueIdentifier”,而不pipe它是如何使用的:

    $ strings libFoo.a | grep uniqueIdentifier

  • 使用nm或otool (请参阅此答案 )

  • 使用otx (见这个答案 )

这些方法可以帮助启动设置断点的潜在调用。