有兩件事,我可以建議,我打賭其中一個(或兩者)是解決您的問題的首要解決方案。
首先,我會聲明k
位於塊的本地,因此不會有覆蓋或不覆蓋的問題。您可能與塊內的kNSNumber
有相同的問題。如果您只是使用該NSNumber實例猛衝multipliedArrayInto
累加器,那麼您可以刪除kNSNumber
,並在其位置使用@(k)
(如果只是爲了更易讀)。同樣,確保multipliedArrayInto
在dispatch_apply
之前被聲明,看起來像是一個外循環(其中i
來自哪裏)。最後,確保resulArray
被實例化,或者在外部for循環之前準備好。
二,是queue
一個併發或串行隊列?如果你正在使用dispatch_apply類似於並行執行/枚舉 - 我認爲這很有可能,所以你正在有效地處理「大數組」 - 然後你實際上保證k
被覆蓋。如果您將其更改爲串行,則可能按設計工作。如果你想要它是平行的,你需要將你的k
累加器的聲明移到塊中,並確保其他變量的聲明也是有意義的。
更新,以反映問題的更新:
@antonytonies理想,在此線程您後續的答案應該被轉移到問題本身,使人們可以按照這個線程更容易。
所以,它看起來像我描述的正是你的問題。
全局隊列都是併發隊列,這意味着(假設)所有的調度塊被一次執行,並且k
內容和其它變量得到吹走取決於塊執行的如何的量級。
我已經採取了你的更新(在「回答」您添加),並修改它可能工作:
// I renamed your method, because nameless parameters pain me. This is cosmetic, and doesn't
// matter for the problem at hand.
- (NSMutableArray *)multiplicationArrays:(NSMutableArray *)array vector:(NSMutableArray *)vector
{
// IMHO, you want to set resultArray to nil here. Another option is to set it to nil in the
// else case, below. Properties in Objective-C are initalized to nil,0,false,etc; you can
// rely on ARC to initialize pointer to objc objects on the stack, too. However, someone
// reading this code may or may not know that. IMHO, using the explicitly assignement makes it
// clear that you're going to be returning `nil` or an instance of `NSMutableArray`.
NSMutableArray *resultArray = nil;
if ([[array objectAtIndex:0] count] == [vector count]) {
// Nicely done w/ pre-allocating the result array here, so that there's no question
// of the indexes matches the results later on.
resultArray = [[NSMutableArray alloc] initWithCapacity:[array count]];
for (int i=0; i < [array count]; i++) {
[resultArray insertObject:[NSNull null] atIndex:i];
}
// 'queue' here is a concurrent queue. This means that you are proclaiming to the runtime
// that the blocks being executed are able to operate correctly w/o interference from each
// other. This is also thought of in terms of parallel execution: all these blocks may run
// **at once**. This *also* means, that you must not share storage between them.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply([array count], queue, ^(size_t j) {
// Moved 'result' inside the block.
NSInteger result = 0;
for (int l = 0; l < [[array objectAtIndex:0] count]; l++) {
// These array reads are **NOT** thread safe. They probably don't cause must trouble in
// practice, but you may want to reconfigure this.
result += [[[array objectAtIndex:j] objectAtIndex:l] intValue] * [[vector objectAtIndex:l] intValue];
}
// The replace of the object into resultArray is **NOT** thread-safe.
// This probably hasn't caused you much trouble, since you can guarantee that
// you aren't writing at the same index. However, I would strongly suggest to
// change this to be thread-safe.
[resultArray replaceObjectAtIndex:j withObject:@(result)];
});
}
else {
NSLog(@"matrix count isn't correspond");
}
return resultArray;
}
最後:使用蘋果的Accelerate框架,這種解決問題的考慮而已。它可在OSX和iOS上使用,因此您應該涵蓋所有基礎。
'你'來自哪裏?除此之外,這看起來充滿了競爭條件。嘗試for或for-each循環,並不需要並行化這種任務。 – diatrevolo
請請將您的Objective-C代碼丟棄並在普通的舊C中執行此操作。Objective-C中不應該這樣做。你的代碼運行速度比應該慢1000倍。並考慮dispatch_apply併發和NSMutableArray不是線程安全的,這是什麼後果。 – gnasher729