在Objective-C块的实现中调用super
10LK
在Objective-C块的实现中是否支持在super上调用方法?
当我呼吁的方法超强的EXC_BAD_ACCESS错误将会被抛出,但只要我改变从这些电话[super methodToCall]
来[self methodToCall]
与松懈响应链的消息,此举它工作得很好。
-methodToCall
块所在的类的实例中没有实现,但超类(即self继承自的类)中没有实现。
我只是想了解有关为什么为什么要在块的实现内部首先在super上调用方法的细节(技术上),所以我将来可以避免它。我怀疑这与如何在块中捕获变量以及有关堆栈和堆的事情有关,但是我确实没有具体想法。
注意:在将块存储在属性中后的几秒钟内,将调用该块实现代码,该属性使用copy,所以我认为块的生命周期没有问题,一切看起来都很好。另外,这仅在iPhone设备(3G)上崩溃,但在iPhone Simulator中没有崩溃。
结果EXC_BAD_ACCESS
:
[self retrieveItemsForId:idString completionHandler:^(NSError *error) { if (!error) { [super didRetrieveItems]; } else { [super errorRetrievingItems]; }}];
工程完善,实现-didRetrieveItems
和-errorRetrievingItems
在超一流的。
[self retrieveItemsForId:idString completionHandler:^(NSError *error) { if (!error) { [self didRetrieveItems]; } else { [self errorRetrievingItems]; }}];
从技术上讲,这是Objective-C运行时以及调用super
实际工作方式的基本机制的问题。基本上,它们既捕获作为消息接收者的对象(self
在所有情况下),也捕获实现方法的特定版本的类(在其中实现方法的类的超类)。由于此类消息发送的很多准备工作是在编译时(而不是运行时)进行的,因此,如果它与块交互不良,我不会感到惊讶。
我将检查self
消息即将发送时是否仍然有效。通常,将自动保留块中引用的任何对象。由于super
工作原理略有不同,这可能意味着它self
不会像人们期望的那样得到保留。一种简单的检查方法是使用super
最初编写的调用,然后简单地泄漏称为的对象self
,然后查看其是否有效。如果这是问题所在,则可能必须self
在该块中插入一个虚拟引用以进行自动内存管理。
但是,从最严格的意义上讲,我不确定您是否可以永远依赖此功能。尽管块可以捕获当前的运行时状态,但从OOP角度来看,它们中断封装并调用超类实现并没有任何意义,因为实现方法的层次结构级别对于任何外部调用代码都是不透明的。我将尝试找到另一种不依赖于继承层次结构的解决方案。


