2008-10-30 76 views
12

我正在寫一個應用程序,執行異步加載圖像到屏幕上。我把它設置爲不併發(即它產生一個線程並一次執行一個線程),所以我只覆蓋了我的NSOperation子類中的[NSOperation main]函數。- [NSOperationQueue操作]應該不會返回一個空數組?

無論如何,所以當我添加所有這些操作時,我希望能夠稍後訪問排隊的操作以更改其優先級。不幸的是,每當我打電話給-[NSOperationQueue operations],我所得到的只是一個空數組。最好的部分是,在放入一些控制檯打印語句之後,儘管數組是空的,線程仍然在隊列中並執行(由打印指示)!

什麼給?爲了確保它們都不是一次執行,我也看了一下帳號,看起來並不是這樣。

任何想法?把這根頭髮拉出來。

編輯:另外值得一提的是,在模擬器上運行:(當相同的代碼提供了全陣列

回答

0

不知道爲什麼您看到此行爲,但作爲一個純粹的解決方法,你可以保持自己的引用給個人因爲它們被添加到隊列中,所以它們的操作都是相同的。

1

我只是不相信這裏有足夠的上下文來說明發生了什麼。看到對象正在運行等。

至於模擬器與iPhone,NSOpe口糧在兩者之間的表現可能完全不同,因爲所有基於Intel的Mac都是多處理器,並且沒有iPhone。根據您試圖限制併發性的方式,您可能處於無法在第二個內核上執行的情況,無法運行,等等。但沒有更多細節,就不可能知道。

0

我在低內存情況下看到了類似的行爲。你使用多少內存?當您收到didReceiveMemoryWarning消息時,您是否正確清除緩存和其他臨時數據?

8

我通過-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 
+0

你在http://bugreport.apple.com報告這一點,如果是這樣,有什麼bug數? – 2009-03-03 23:34:43

0

我只是碰到了同樣的問題。比我在OS X應用上使用的代碼更簡單,但[myoperationqueue操作]總是返回nil。我打算使用它來避免重複查詢。這是在iPhone OS 2.2.1上。當然,這似乎是一個錯誤。感謝代碼,我可以使用它,或者使用我自己的隊列鏡像。

這不是在模擬器上,我確認我添加了20個或完全相同的作業副本,所有這些都很好地排隊,並且做了19次這樣的工作!

這真的很簡單的代碼。我幾乎沒有使用任何內存 - 這是推出一個沒有用戶界面的應用程序。

--Tom

相關問題