我通過-operations
加強,並發現它基本上是這樣做的:
[self->data->lock lock];
NSString* copy = [[self->data->operations copy] autorelease];
[self->data->lock unlock];
return copy;
除,呼籲-autorelease
後,隨後的指令覆蓋包含唯一的指針操作隊列中的新副本的寄存器。來電者然後獲得nil
返回值。所述「data
」字段是命名爲_NSOperationQueueData
一個內部類具有字段的一個實例:
NSRecursiveLock* lock;
NSArray* operations;
我的解決辦法是子類,並覆蓋-operations
,以下相同的邏輯,但實際上返回數組副本。如果NSOperationQueue
的內部版本與此修補程序不兼容,我添加了一些完整性檢查來保護它們。只有在調用[super operations]
確實返回nil
時纔會調用此重新實現。
如果Apple要改變內部結構,這可能會在未來的操作系統發行版中崩潰,但不知何故可以避免實際修復此錯誤。
#if TARGET_OS_IPHONE
#import <objc/runtime.h>
@interface _DLOperationQueueData : NSObject {
@public
id lock; // <NSLocking>
NSArray* operations;
}
@end
@implementation _DLOperationQueueData; @end
@interface _DLOperationQueueFix : NSObject {
@public
_DLOperationQueueData* data;
}
@end
@implementation _DLOperationQueueFix; @end
#endif
@implementation DLOperationQueue
#if TARGET_OS_IPHONE
-(NSArray*) operations
{
NSArray* operations = [super operations];
if (operations != nil) {
return operations;
}
_DLOperationQueueFix* fix = (_DLOperationQueueFix*) self;
_DLOperationQueueData* data = fix->data;
if (strcmp(class_getName([data class]), "_NSOperationQueueData") != 0) {
// this hack knows only the structure of _NSOperationQueueData
// anything else, bail
return operations;
}
if ([data->lock conformsToProtocol: @protocol(NSLocking)] == NO) {
return operations; // not a lock, bail
}
[data->lock lock];
operations = [[data->operations copy] autorelease];
[data->lock unlock];
return operations; // you forgot something, Apple.
}
#endif
@end
頭文件是:
@interface DLOperationQueue : NSOperationQueue {}
#if TARGET_OS_IPHONE
-(NSArray*) operations;
#endif
@end
你在http://bugreport.apple.com報告這一點,如果是這樣,有什麼bug數? – 2009-03-03 23:34:43