如何设置断点“objectAtIndex:”特定属性的方法,在特定类的XCode 4?(How to

2019-08-03 20:00发布

我想设置一个断点象征“objectAtIndex:”特定属性的方法,在一个特定的类。

请看下面的代码:

@interface Foo
...
@property (strong,nonatomic) NSMutableArray *fooArray;
...
@end

我已经尝试了以下几件事:

  • -[[Foo fooArray] objectAtIndex:]
  • -[Foo::fooArray objectAtIndex:]
  • -[Foo::fooArray objectAtIndex]
  • Foo::fooArray::objectAtIndex:
  • Foo::fooArray::objectAtIndex
  • Foo::fooArray::objectAtIndex()

无的论文解决方案的工作。

任何想法做的伎俩?

Answer 1:

不幸的是,虽然这将是有益的,它不能正常工作,出于多种原因。

第一个涉及如何规定的方法。 用于在断点识别的方法的方法签名有三个部分:

-¹[NSDictionary² objectForKey:³]
+¹[NSString² stringWithContentsOfURL:encoding:error:³]
  1. 这是一个实例方法( - )或一个类的方法(+)?
  2. 哪一类的此方法的实现?
  3. 这是什么方法的选择?

所以,你的第一个问题是,你已经写了#2究竟是不是一类。

你有什么是一类,由属性名称后以某种方式。 这可不行,因为调试器没有办法知道这是否是一个纯粹的访问,它不能确保您,或者谁实施了财产,没有写一个自定义的访问,做别的东西。 这意味着调试器有没有好的,可靠的方式来获得价值,或者知道价值的变化,而不招致的潜在副作用时。

此外,在方法签名类的作用是识别类提供你在设置断点的实现。 ,一旦走出窗口,当你开始想指的是持有的对象,而不是一个属性,因为调试器需要一个类,必须从一开始就对象,看看前一段一段的困难了解哪些对象,它是在任何时候。

(公平地说,这确实是可能的调试器观看一个实例变量,IIRC的价值,无论是调试器已经可以在一个观察点做到这一点,虽然观察点的可靠性呈片状我最后一次尝试之一。如果调试器可以在财产转化为后盾伊娃,如果有的话,看的是,这将是广大的属性,这是不是想象力存储实现和自定义访问器支持的一个体面的90%的溶液,但调试器无法做到今天这个。)

第二个原因是,NSArray的是一类集群。

您可能已经知道这第一部分(我怀疑这就是为什么你试图通过另一个属性来指定一个对象):

NSArray的和的NSMutableArray都是抽象类,这反过来又意味着,没有一个实现的是阵列中的业务; 每一个实现了一堆的便利方法,同时留下一个选择集的未执行的核心方法,子类实现。

所以,当你创建一个NSArray,你不创建一个NSArray。 你得到的对象将是NSArray中的一些私人子类的实例,用它自己的实现所有的如何管理对象的有序列表中的细节。

所以,你可以设置,比如说一个断点, -[NSArray objectAtIndex:] ,但它永远不会被击中,因为没有使用NSArray的实施objectAtIndex: -它是没有意义的使用该实现,因为实现抛出一个例外(为了赶上忘记实现它)的子类。

打破你的问题的部分是:

虽然各种非必要的方法NSArray的实现,在核心方法,如术语定义最终objectAtIndex:这并不意味着子类势必会动用这些实现。 子类很可能有自己的实现不使用objectAtIndex:如果objectAtIndex:是不是最有效的方式做到他们这样做(例如,如果该阵列由一个链表,而不是C数组的支持)的东西。

因此,要总结这漫长的答案:

  • 这是不可能的调试器能够可靠地观看属性的值。
  • 因此,它是不可能的调试器打破当在类,它是该属性的值的对象的方法被调用,因为正确的方法来设置上可在任何时间改变断点,调试器不能知道当这种情况发生。
  • 即使你能打破上objectAtIndex:由属性标识的一些对象,该阵列可以有效地从不使用objectAtIndex:在这种情况下,您的断点将永远不会无论如何击中。

你或许应该问任何你正在试图打破对做另一个问题objectAtIndex: 我假设你想调查您的应用程序中的错误; 该错误可能是另一种有趣的问题。



Answer 2:

一些挖后,我发现了一个办法来解决这一问题。 这是有点难看。

它涉及一种动态地创建条件断点,在由第一个断点触发命令。

首先,打破,只要您fooArray已准备就绪。 我看中的fooArray访问,但它可以做得比较早:

breakpoint set --name "-[Foo fooArray]"

然后,你需要的是休息的时候objectAtIndex:被称为这个特定阵列对象。 首先,让我们把它的指针变量:

expr id $watch = self->_fooArray

然后创建一个新的断点,使用条件这个变量:

breakpoint set --name "-[__NSArrayI objectAtIndex:]" --condition "$rdi == $watch"

  • $rdi包含self ,至少在x86_64 。 使用$r0上ARM。 (见克拉克考克斯的话题伟大的职位 。)
  • -[NSArray objectAtIndex:]永远不会被调用。 正如彼得所说,NSArray的是一类集群,和你的数组实际上是一个__NSArrayI

或者,在Xcode:

(不要忘记检查“继续”复选框。)

这不是真的很漂亮,但似乎工作!



Answer 3:

我不是在我的Mac,所以我不能这个尝试我自己,但如何:

breakpoint set -n "-[[Foo fooArray] objectAtIndex:]" 


文章来源: How to set a breakpoint on “objectAtIndex:” method of a specific property in a specific class in XCode 4?