2017-06-09 94 views
0

我有一個算法來識別照片中的對象。主要的問題是它不是線程安全的,所以e.x.當你設置一個新的配置文件或者當你開始處理一個新的圖像,但仍然存在處理差異時,算法的行爲是不確定的,並且可能會崩潰。下面我把我的代碼和我的實現不好。線程安全處理

// config struct 
public struct Config {} 

// reslut of the algorithm 
public struct Product {} 

// algorith class 
public class Recognizer { 
    func apply(config: Config) 
    func process(frame: UIImage) -> Product { 
     let prodcut = Product() 
     return prodcut 
    } 
} 

// protocol for an object interested in the result of the Recognizer 
protocol Observer: class { 
    func didProcess(frame: UIImage, prodcut: Prodcut) 
} 

// protocol that wraps Recognizer class 
protocol RecognizerService { 
    func add(observer: Observer) 
    func remove(observer: Observer) 
    var recognitionConfig: Config { get set } 
    func process(frame: UIImage) 
} 

下面是它的外觀。

let recognizerQueue: DispatchQueue = DispatchQueue.global(qos: .background) 

class HumanFaceRecognizer: RecognizerService { 
     var recognitionConfig: Config 
     var observers: [Observer] 
     let algorythm: Recognizer 
     private var recognizerQueue: DispatchQueue 

     init(recognitionConfig: Config, 
      observers: [Observer] = [], 
      recognizerQueue: DispatchQueue, 
      algorythm: Recognizer) { 
      self.recognitionConfig = recognitionConfig 
      self.observers = observers 
      self.recognizerQueue = recognizerQueue 
      self.algorythm = algorythm 
     } 

     func add(observer: Observer) { 
      observers.append(observer) 
     } 

     func remove(observer: Observer) { 
      observers.remove(observer) 
     } 

     func process(frame: UIImage) { 
      recognizerQueue.async { [weak self, currentFrame = frame, currentConfig = recognitionConfig] in 
      self?.algorythm.process(frame: currentFrame) 
      observers.forEach { $0.didProcess(frame: currentFrame, result: currentConfig) } 
     } 
} 

我覺得我做錯了什麼與調度此計算背景,但我不能找到合適的解決方案來做到這一點。

回答

0

我認爲您提供的代碼不足以明確回答您的問題。如果您發佈您的崩潰等一些調用堆棧這將是有益

的第一個想法是:

  • 也許觀察者不能夠從任意線程(全球隊列)被調用,因爲他們的表現一些UI更新等。在這種情況下,您可以從主隊列調用didProcess
  • 也許有一些問題,有些觀察員將他們從HumanFaceRecognizer中刪除,而他們在didProcess中被調用,即forEach調用對修改後的集合起作用。在這種情況下,您應該在遍歷它之前複製observers數組。
  • 你也可以嘗試(深)複製算法類,以使其「更加」線程安全

希望這有助於有點:-)