Обновление пользовательского интерфейса при работе с OperationQueue - PullRequest
1 голос
/ 28 мая 2020

У меня есть следующая настройка очереди операций:

let queue = OperationQueue()
queue.name = "com.company.myQueue"
queue.qualityOfService = .userInitiated
queue.maxConcurrentOperationCount = 64
...
var current = 0
var totalCount = someArray.count
for i in someArray {
... 
   let op = BlockOperation {
   ... // do some database queries
   current += 1
   }

   op.completionBlock = {
     DispatchQueue.main.async {
     let nData: [String: CGFloat] = ["value": CGFloat(current/totalCount)]
     NotificationCenter.default.post(name:Notification.Name(rawValue: "update"), object: nil, userInfo: nData)
   }

   queue.addOperation(op)
}

В моем ViewController я слушаю уведомление и обновляю UILabel с процентом. Проблема в том, что хотя я не получаю никаких промежуточных значений ... он переходит с 0 прямо на 100 после того, как все операции выполнены.

Что я делаю не так?

Спасибо

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Проблема: CGFloat(current / totalCount). Сначала выполняется целочисленная математика, а затем она преобразуется в число с плавающей запятой. Вы должны перевернуть это на CGFloat(current) / CGFloat(totalCount).

1 голос
/ 28 мая 2020

Вы можете переместить функцию отправки уведомлений прямо в op.completionBlock (без отправки ее в основной поток).

Edit (комментарии):

let queue = OperationQueue()
    queue.name = "com.company.myQueue"
    queue.qualityOfService = .userInitiated
    queue.maxConcurrentOperationCount = 64

let array = ["", "", "", "", "", ]

var current = 0
var totalCount = array.count

for _ in array {
    let op = BlockOperation { current += 1 ; print(current) }
        op.completionBlock = {
            DispatchQueue.main.async {
                NotificationCenter.default.post(name: Notification.Name(rawValue: "update"), object: nil, userInfo: ["value": CGFloat(current / totalCount)])
            }
        }

   queue.addOperation(op)
}

NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "update"), object: nil, queue: nil) { (notification) in
    print(notification.userInfo)
}

Edit 2 (комментарии): Перед их делением вы должны получить свой процент, используя значение float casting current и totalCount.

CGFloat(current) / CGFloat(totalCount)
'''
...