2015-05-01 3 views
4

Привет Я создаю приложение с помощью Swift. Мне нужно обрабатывать уведомления в определенном порядке. Поэтому я пытаюсь использовать addOperations waitUntilFinished.NSOperationQueue addOperations waitUntilFinished

Вот что я сделал:

let oldify = NSOperation() 
    oldify.completionBlock = { 
println("oldify") 
} 
let appendify = NSOperation() 
    appendify.completionBlock = { 
println("appendify") 
} 
let nettoyify = NSOperation() 
    nettoyify.completionBlock = { 
println("nettoyify") 
} 
NSOperationQueue.mainQueue().maxConcurrentOperationCount = 1 
NSOperationQueue.mainQueue().addOperations([oldify, appendify, nettoyify], waitUntilFinished: true) 

С помощью этого кода ни один из операций выполняется. Когда я попробую это вместо этого:

NSOperationQueue.mainQueue().maxConcurrentOperationCount = 1 
NSOperationQueue.mainQueue().addOperation(oldify) 
NSOperationQueue.mainQueue().addOperation(appendify) 
NSOperationQueue.mainQueue().addOperation(nettoyify) 

Операции выполняются, но не в правильном порядке.

Кто-нибудь знает, что я делаю неправильно? Я получаю уверен в быстр, но совершенно новом для NSOperations

+0

возможно дубликат [NSOperationQueue очереди последовательного FIFO] (http://stackoverflow.com/questions/10948804/nsoperationqueue-serial-fifo-queue) – Azat

ответ

5

Пары вопросов:

  1. Вы изучаете поведение завершения блока обработчиков. Как указано в документации completionBlock:

    Точный контекст выполнения для вашего блока завершения не гарантируется, но обычно является вторичным потоком. Поэтому вы не должны использовать этот блок для выполнения любой работы, требующей особого контекста выполнения.

    Очередь будет управлять сами операции, но не их завершающие блоки (короткие убедившись, что операция завершается до его completionBlock запускается). Итак, в нижней строке не делайте никаких предположений о (а), когда выполняются блоки завершения, (б) отношение одной операции completionBlock к другим операциям или их блокам completionBlock и т. Д., И (в), какой поток они выполняются на ,

  2. Операции обычно выполняются в том порядке, в котором они были добавлены в очередь. Однако, если вы добавляете массив операций, документация не дает никаких официальных заверений в том, что они находятся в очереди в том порядке, в котором они отображаются в этом массиве. Поэтому вы можете добавить операции по одному.

  3. Сказав, что документация идет на нас предупредить:

    Операция очередь выполняет свои очереди объектов операции на основе их приоритета и готовности. Если все объекты очереди в очереди имеют одинаковый приоритет и готовы к выполнению, когда они помещаются в очередь, то есть их метод isReady возвращает YES - они выполняются в том порядке, в котором они были отправлены в очередь. Однако вы никогда не должны полагаться на семантику очереди, чтобы обеспечить конкретный порядок выполнения объектов операций. Изменения в готовности операции могут изменить результирующий порядок выполнения. Если вам нужны операции для выполнения в определенном порядке, используйте зависимости уровня операций, определенные классом NSOperation.

    Для установления явных зависимостей, вы могли бы сделать что-то вроде:

    let oldify = NSBlockOperation() { 
        NSLog("oldify") 
    } 
    oldify.completionBlock = { 
        NSLog("oldify completion") 
    } 
    
    let appendify = NSBlockOperation() { 
        NSLog("appendify") 
    } 
    appendify.completionBlock = { 
        NSLog("appendify completion") 
    } 
    
    appendify.addDependency(oldify) 
    
    let nettoyify = NSBlockOperation() { 
        NSLog("nettoyify") 
    } 
    nettoyify.completionBlock = { 
        NSLog("nettoyify completion") 
    } 
    
    nettoyify.addDependency(appendify) 
    
    let queue = NSOperationQueue() 
    queue.addOperations([oldify, appendify, nettoyify], waitUntilFinished: false) 
    
  4. Кстати, как вы будете видеть выше, вы не должны добавлять операции в основную очередь в сочетании с waitUntilFinished.Не стесняйтесь добавлять их в другую очередь, но не отправляйте из последовательной очереди, обратно к себе, с опцией waitUntilFinished.

+0

Большое спасибо @Rob. Теперь это выглядит намного яснее. Тем не менее, я все еще сталкиваюсь с проблемой. В блоке appendify я запускаю запрос на анализ, используя 'findObjectsInBackgroundWithBlock'. Результатом является то, что oldify, appendify и nettoyify выполняются в правильном порядке, но запрос (предположительно внутри appendify) возвращает результаты после всего. Я пытаюсь выполнить этот запрос в основном потоке, поскольку я уже установил 'queue.qualityOfService = NSQualityOfService.UserInitiated' –

+0

Ваши операции выполняются' findObjectsInBackgroundWithBlock'? Если это так, это асинхронный запрос, поэтому я уверен, что ваша операция, скорее всего, завершится до того, как будет выполнен запрос Parse. Два решения: либо оберните их в асинхронный подкласс NSOperation, который только вручную завершит операцию, когда запрос будет выполнен, либо вместо того, чтобы ваши операции выдавали синхронные запросы (но не забудьте добавить эти операции в свою очередь, а не в основную очередь). – Rob

+0

Большое спасибо @Rob. Я выбираю выполнять синхронные запросы, используя '.find()' вместо 'findObjectsInBackgroundWithBlock'. Однако мне пришлось установить 'waitUntilFinished' в true. Это проблема, поскольку все это не происходит в главной очереди? –

Смежные вопросы