যখন NSOperationQueue সমস্ত কাজ শেষ করে বিজ্ঞপ্তি পান


93

NSOperationQueueআছে waitUntilAllOperationsAreFinished, তবে আমি এর জন্য একযোগে অপেক্ষা করতে চাই না। সারি শেষ হওয়ার পরে আমি কেবলমাত্র ইউআইতে অগ্রগতি সূচকটি আড়াল করতে চাই।

এটি সম্পাদন করার সর্বোত্তম উপায় কী?

আমি আমার NSOperationএস থেকে বিজ্ঞপ্তিগুলি পাঠাতে পারি না , কারণ কোনটি শেষ হতে চলেছে তা আমি জানি না এবং বিজ্ঞপ্তি পাওয়ার পরে [queue operations]খালি (বা আরও খারাপ - পুনর্নির্মাণ) হতে পারে না।


আপনি যদি সুইফড
অভিজিৎ

উত্তর:


167

operationsআপনার সারির সম্পত্তিটি পর্যবেক্ষণ করতে কেভিও ব্যবহার করুন , তারপরে আপনার সারির পরীক্ষাটি শেষ করে শেষ হয়েছে কিনা তা আপনি বলতে পারবেন [queue.operations count] == 0

যে ফাইলটিতে আপনি কেভিও করছেন সেখানে কোথাও কেভিওর জন্য একটি প্রসঙ্গ ঘোষণা করুন ( আরও তথ্য ):

static NSString *kQueueOperationsChanged = @"kQueueOperationsChanged";

আপনি যখন আপনার সারি সেটআপ করবেন, তখন এটি করুন:

[self.queue addObserver:self forKeyPath:@"operations" options:0 context:&kQueueOperationsChanged];

তারপরে এটি আপনার করুন observeValueForKeyPath:

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                         change:(NSDictionary *)change context:(void *)context
{
    if (object == self.queue && [keyPath isEqualToString:@"operations"] && context == &kQueueOperationsChanged) {
        if ([self.queue.operations count] == 0) {
            // Do something here when your queue has completed
            NSLog(@"queue has completed");
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object 
                               change:change context:context];
    }
}

(এটি ধরে নেওয়া হচ্ছে যে আপনার NSOperationQueueনামের কোনও সম্পত্তিতে রয়েছে queue)

আপনার অবজেক্টটি পুরোপুরি deallocs করার আগে (বা যখন এটি সারি অবস্থার বিষয়ে যত্ন নেওয়া বন্ধ করে), আপনাকে কেভিও থেকে এইভাবে নিবন্ধন করতে হবে:

[self.queue removeObserver:self forKeyPath:@"operations" context:&kQueueOperationsChanged];


সংযোজন: আইওএস ৪.০ এর একটি NSOperationQueue.operationCountসম্পত্তি রয়েছে, যা ডক্স অনুসারে কেভিও অনুগত। এই উত্তরটি এখনও আইওএস ৪.০ এ কাজ করবে, সুতরাং এটি পিছনের সামঞ্জস্যের জন্য এখনও কার্যকর।


26
আমি যুক্তি দিয়ে বলব যে আপনার সম্পত্তি অ্যাক্সেসর ব্যবহার করা উচিত, যেহেতু এটি ভবিষ্যতে-প্রমাণিত এনক্যাপসুলেশন সরবরাহ করে (যদি আপনি উদাহরণস্বরূপ সিদ্ধান্ত নেন যে সারিটি অলস-প্রাথমিককরণ)। সরাসরি আইভার দ্বারা কোনও সম্পত্তি অ্যাক্সেস অকাল অপ্টিমাইজেশন হিসাবে বিবেচনা করা যেতে পারে, তবে এটি সত্যিকারের প্রসঙ্গে নির্ভর করে। আইভারের মাধ্যমে কোনও সম্পত্তিতে সরাসরি অ্যাক্সেসের মাধ্যমে সাশ্রয় করা সময়টি সাধারণত নগণ্য হতে চলেছে, যদি না আপনি সেই সম্পত্তিটিকে সেকেন্ডে 100-1000 গুণ বেশি উল্লেখ করেন (অবিশ্বাস্যরূপে অপরিশোধিত অনুমান হিসাবে)।
নিক

4
খারাপ কেভিও ব্যবহারের কারণে ডাউনভোটে প্রলুব্ধ হয়েছে। যথাযথ ব্যবহার এখানে বর্ণিত হয়েছে: dribin.org/dave/blog/archives/2008/09/24/proper_kvo_usage
নিকোলাই রুহে

19
@ নিকোলাইরুহে আপনি সঠিক - এই কোডটি ব্যবহার করে যখন কোনও ক্লাস সাব-ক্লাসিং করা যা নিজে নিজেই operationCountএকই জিনিসটিতে পর্যবেক্ষণ করতে কেভিও ব্যবহার করে তখন NSOperationQueueসম্ভবত বাগগুলি নিয়ে যেতে পারে, সেক্ষেত্রে আপনাকে প্রসঙ্গ যুক্তিটি সঠিকভাবে ব্যবহার করতে হবে। এটি হওয়ার সম্ভাবনা নেই, তবে অবশ্যই সম্ভব। (আসল সমস্যাটি বানান স্নার্ক + একটি লিঙ্ক যুক্ত করার চেয়ে আরও সহায়ক)
নিক

6
একটি আকর্ষণীয় ধারণা এখানে পেয়েছি । আমি NSOperationQueue সাবক্লাসে এটি ব্যবহার করেছি, একটি NSOperation সম্পত্তি, 'ফাইনাল ওপিয়েশন' যোগ করেছি, যা কাতারে যুক্ত প্রতিটি অপারেশনের নির্ভরশীল হিসাবে সেট করা আছে। স্পষ্টতই অ্যাডঅপারেশনকে ওভাররাইড করতে হয়েছিল: এটি করার জন্য। চূড়ান্ত অপারেশন সম্পূর্ণ হওয়ার সাথে সাথে একটি প্রোটোকল যুক্ত করেছে যা একটি প্রতিনিধিকে একটি চিত্র পাঠায়। এতক্ষণ কাজ করে যাচ্ছি।
pnizzle

4
অনেক ভাল! অপশনগুলি নির্দিষ্ট করা হলে আমি সবচেয়ে বেশি খুশি হব এবং অপসারণকারক: কলটি একটি @ ট্রাই / @ ক্যাপ দ্বারা আবৃত হয় - এটি আদর্শ নয় তবে অ্যাপল ডক্স উল্লেখ করে যে রিমুব ওভার্সার কল করার সময় কোনও সুরক্ষা নেই: ... যদি বস্তুর কোনও পর্যবেক্ষক নিবন্ধকরণ নেই অ্যাপ্লিকেশনটি ক্রাশ হবে।
অস্টিন

20

যদি আপনি এমন আচরণের সাথে মেলে এমন কিছু প্রত্যাশা (বা আকাঙ্ক্ষা) করছেন:

t=0 add an operation to the queue.  queueucount increments to 1
t=1 add an operation to the queue.  queueucount increments to 2
t=2 add an operation to the queue.  queueucount increments to 3
t=3 operation completes, queuecount decrements to 2
t=4 operation completes, queuecount decrements to 1
t=5 operation completes, queuecount decrements to 0
<your program gets notified that all operations are completed>

আপনার সচেতন হওয়া উচিত যে যদি "শর্ট" ক্রিয়াকলাপগুলিকে একটি কাতারে যুক্ত করা হয় তবে আপনি পরিবর্তে এই আচরণটি দেখতে পাবেন (কারণ কাতারে যুক্ত হওয়ার অংশ হিসাবে অপারেশনগুলি শুরু হয়েছে):

t=0  add an operation to the queue.  queuecount == 1
t=1  operation completes, queuecount decrements to 0
<your program gets notified that all operations are completed>
t=2  add an operation to the queue.  queuecount == 1
t=3  operation completes, queuecount decrements to 0
<your program gets notified that all operations are completed>
t=4  add an operation to the queue.  queuecount == 1
t=5  operation completes, queuecount decrements to 0
<your program gets notified that all operations are completed>

আমার প্রকল্পে আমাকে জানতে হবে শেষ অপারেশনটি কখন শেষ হয়েছিল, প্রচুর ক্রিয়াকলাপটি সিরিয়াল NSOperationQueue (অর্থাত্, ম্যাকসকন্ট্রোরঅপারেশনকন্ট = 1) এ যুক্ত হওয়ার পরে এবং যখন তারা সমস্ত সম্পন্ন করেছিল তখনই।

গুগলিং আমি এই প্রশ্নের জবাবে একজন অ্যাপল বিকাশকারীর কাছ থেকে এই বিবৃতিটি খুঁজে পেয়েছি "সিরিয়াল এনএস্পেরেশনকিউ ফিফো?" -

যদি সমস্ত ক্রিয়াকলাপের একই অগ্রাধিকার থাকে (যা অপারেশনটিকে একটি সারি যুক্ত করার পরে পরিবর্তন করা হয় না) এবং সমস্ত ক্রিয়াকলাপ সর্বদা হয় - isReady == হ্যাঁ অপারেশন কাতারে উপস্থিত হওয়ার পরে, তবে একটি সিরিয়াল NSOperationQueue ফিফো।

ক্রিস কেন কোকো ফ্রেমওয়ার্কস, অ্যাপল

আমার ক্ষেত্রে এটি শেষের অপারেশনটি কাতারে কখন যুক্ত হয়েছিল তা জানা সম্ভব। সুতরাং শেষ অপারেশন যুক্ত হওয়ার পরে, আমি কাতারে আরও অপারেশন যুক্ত করছি, নিম্ন অগ্রাধিকারের, যা সারিটি খালি করা হয়েছে বলে বিজ্ঞপ্তি পাঠানো ছাড়া কিছুই করে না। অ্যাপলের বিবৃতি দেওয়া, এটি নিশ্চিত করে যে সমস্ত ক্রিয়াকলাপ সম্পন্ন হওয়ার পরে কেবলমাত্র একটি নোটিশ পাঠানো হবে।

যদি অপারেশনগুলি এমনভাবে যুক্ত করা হয় যা শেষটিকে সনাক্ত করতে দেয় না, (উদাহরণস্বরূপ, অ-সংজ্ঞাবাদী) তবে আমি মনে করি যে আপনাকে উপরে উল্লিখিত কেভিও পদ্ধতির সাথে যেতে হবে, অতিরিক্ত গার্ড যুক্তি যুক্ত করে আরও চিহ্নিত করার চেষ্টা করার চেষ্টা করা হয়েছে অপারেশন যোগ করা যেতে পারে।

:)


হাই, আপনি কি জানেন যে কাতারে প্রতিটি ক্রিয়াকলাপটি সর্বাধিক সংক্ষিপ্তর অপারেশনকন্ট = 1 এর সাথে একটি এনএসওপরেশনকুইউ ব্যবহার করে শেষ হলে কীভাবে এবং কীভাবে বিজ্ঞপ্তি দেওয়া সম্ভব?
সেফরান 2

@ ফ্রান: আমি অপারেশনগুলি সম্পূর্ণ হওয়ার পরে একটি বিজ্ঞপ্তি পোস্ট করব। এইভাবে অন্যান্য মডিউলগুলি পর্যবেক্ষক হিসাবে নিবন্ধভুক্ত করতে এবং প্রতিটি সম্পূর্ণ হওয়ার সাথে সাথে প্রতিক্রিয়া জানাতে পারে। যদি আপনার @ নির্বাচক কোনও নোটিফিকেশন অবজেক্ট নেয় আপনি সহজেই কী বিজ্ঞপ্তিটি পোস্ট করেছেন সেই অবজেক্টটি পুনরুদ্ধার করতে পারবেন, সেক্ষেত্রে সবেমাত্র কী সম্পন্ন হয়েছে সে সম্পর্কে আপনার আরও বিশদ প্রয়োজন।
সফটওয়্যারটি

17

কীভাবে এমন এনএসওপ্রেশন যুক্ত করবেন যা অন্য সকলের উপর নির্ভরশীল যাতে এটি শেষ পর্যন্ত চলে?


4
এটি কার্যকর হতে পারে তবে এটি একটি হেভিওয়েট সমাধান এবং আপনার যদি কাতারে নতুন কাজ যুক্ত করার প্রয়োজন হয় তবে এটি পরিচালনা করতে ব্যথা হবে।
কর্নেল

এটি আসলে খুব মার্জিত এবং আমি যেটিকে সবচেয়ে বেশি পছন্দ করি! আপনি আমার ভোট।
ইয়ারিভ নিসিম

4
ব্যক্তিগতভাবে এটি আমার প্রিয় সমাধান। সমাপ্তি ব্লকের জন্য আপনি সহজেই একটি সাধারণ এনএসব্লকওপ্রেশন তৈরি করতে পারেন যা অন্যান্য সমস্ত ক্রিয়াকলাপের উপর নির্ভর করে।
পুনেতে শেঠি

আপনি এমন একটি সমস্যায় পড়তে পারেন যে সারিটি বাতিল হয়ে গেলে এনএসব্লকঅপেশনকে ডাকা হয় না। সুতরাং আপনাকে নিজের অপারেশন তৈরি করতে হবে যা বাতিল হওয়ার সময় ত্রুটি সৃষ্টি করে এবং একটি ত্রুটি প্যারামের সাথে একটি ব্লককে কল করে।
মালহাল

এটাই সেরা উত্তর!
ট্র্যাপার

12

এর একটি বিকল্প হ'ল জিসিডি ব্যবহার করা। পড়ুন এই রেফারেন্স হিসেবে।

dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,queue,^{
 NSLog(@"Block 1");
 //run first NSOperation here
});

dispatch_group_async(group,queue,^{
 NSLog(@"Block 2");
 //run second NSOperation here
});

//or from for loop
for (NSOperation *operation in operations)
{
   dispatch_group_async(group,queue,^{
      [operation start];
   });
}

dispatch_group_notify(group,queue,^{
 NSLog(@"Final block");
 //hide progress indicator here
});

5

এইভাবেই আমি এটি করি।

সারিটি সেট আপ করুন, এবং ক্রিয়াকলাপ সংস্থার পরিবর্তনের জন্য নিবন্ধন করুন:

myQueue = [[NSOperationQueue alloc] init];
[myQueue addObserver: self forKeyPath: @"operations" options: NSKeyValueObservingOptionNew context: NULL];

... এবং পর্যবেক্ষক (এই ক্ষেত্রে self) প্রয়োগগুলি:

- (void) observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context {

    if (
        object == myQueue
        &&
        [@"operations" isEqual: keyPath]
    ) {

        NSArray *operations = [change objectForKey:NSKeyValueChangeNewKey];

        if ( [self hasActiveOperations: operations] ) {
            [spinner startAnimating];
        } else {
            [spinner stopAnimating];
        }
    }
}

- (BOOL) hasActiveOperations:(NSArray *) operations {
    for ( id operation in operations ) {
        if ( [operation isExecuting] && ! [operation isCancelled] ) {
            return YES;
        }
    }

    return NO;
}

এই উদাহরণে "স্পিনার" UIActivityIndicatorViewএমন কিছু দেখাচ্ছে যা কিছু ঘটছে is অবশ্যই আপনি মামলা অনুসারে পরিবর্তন করতে পারেন ...


4
এই forলুপটি সম্ভাব্য ব্যয়বহুল বলে মনে হচ্ছে (আপনি যদি একই সাথে সমস্ত ক্রিয়াকলাপ বাতিল করেন তবে কি? সারি পরিষ্কার করার সময় চতুষ্পদ পারফরম্যান্সটি পাবেন না?)
কর্নেল

দুর্দান্ত একটি, তবে থ্রেডগুলির সাথে সাবধানতা অবলম্বন করুন, কারণ ডকুমেন্টেশন অনুসারে: "... অপারেশন সারির সাথে সম্পর্কিত কেভিও বিজ্ঞপ্তিগুলি কোনও থ্রেডে ঘটতে পারে" " সম্ভবত, স্পিনারকে আপডেট করার আগে আপনাকে এক্সিকিউশন
ফ্লোটি

4

এর মতো আইওএস 13.0 , operationCount এবং অপারেশন বৈশিষ্ট্য অবচিত করছে। আপনার কাতারে ক্রিয়াকলাপের সংখ্যাটি নিজের উপর নজর রাখা এবং সমস্ত কিছু শেষ হয়ে গেলে কোনও বিজ্ঞপ্তি বন্ধ করে দেওয়া ঠিক তত সহজ । এই উদাহরণটি অপারেশনের একটি অ্যাসিনক্রোনাস সাবক্লাসিংয়ের সাথেও কাজ করে।

class MyOperationQueue: OperationQueue {
            
    public var numberOfOperations: Int = 0 {
        didSet {
            if numberOfOperations == 0 {
                print("All operations completed.")
                
                NotificationCenter.default.post(name: .init("OperationsCompleted"), object: nil)
            }
        }
    }
    
    public var isEmpty: Bool {
        return numberOfOperations == 0
    }
    
    override func addOperation(_ op: Operation) {
        super.addOperation(op)
        
        numberOfOperations += 1
    }
    
    override func addOperations(_ ops: [Operation], waitUntilFinished wait: Bool) {
        super.addOperations(ops, waitUntilFinished: wait)
        
        numberOfOperations += ops.count
    }
    
    public func decrementOperationCount() {
        numberOfOperations -= 1
    }
}

নীচে সহজ অ্যাসিনক্রোনাস অপারেশনগুলির জন্য অপারেশনের একটি উপক্লাস রয়েছে

class AsyncOperation: Operation {
    
    let queue: MyOperationQueue

enum State: String {
    case Ready, Executing, Finished
    
    fileprivate var keyPath: String {
        return "is" + rawValue
    }
}

var state = State.Ready {
    willSet {
        willChangeValue(forKey: newValue.keyPath)
        willChangeValue(forKey: state.keyPath)
    }
    
    didSet {
        didChangeValue(forKey: oldValue.keyPath)
        didChangeValue(forKey: state.keyPath)
        
        if state == .Finished {
            queue.decrementOperationCount()
        }
    }
}

override var isReady: Bool {
    return super.isReady && state == .Ready
}

override var isExecuting: Bool {
    return state == .Executing
}

override var isFinished: Bool {
    return state == .Finished
}

override var isAsynchronous: Bool {
    return true
}

public init(queue: MyOperationQueue) {
    self.queue = queue
    super.init()
}

override func start() {
    if isCancelled {
        state = .Finished
        return
    }
    
    main()
    state = .Executing
}

override func cancel() {
    state = .Finished
}

override func main() {
    fatalError("Subclasses must override main without calling super.")
}

}


decrementOperationCount()পদ্ধতিটি কোথায় ডাকা হয়?
iksnae

@ আইকসনা - আমি আমার উত্তরটি অপারেশনের একটি সাবক্লাস দিয়ে আপডেট করেছি । আমি আমার রাষ্ট্রের ভেরিয়েবলের ডডসেটের মধ্যে ডিমেমেন্টঅপারেশন অ্যাকাউন্ট () ব্যবহার করি । আশাকরি এটা সাহায্য করবে!
কালেব লিন্ডসে

3

আমি এটি করতে একটি বিভাগ ব্যবহার করছি।

NSOperationQueue + সমাপ্তি

//
//  NSOperationQueue+Completion.h
//  QueueTest
//
//  Created by Artem Stepanenko on 23.11.13.
//  Copyright (c) 2013 Artem Stepanenko. All rights reserved.
//

typedef void (^NSOperationQueueCompletion) (void);

@interface NSOperationQueue (Completion)

/**
 * Remarks:
 *
 * 1. Invokes completion handler just a single time when previously added operations are finished.
 * 2. Completion handler is called in a main thread.
 */

- (void)setCompletion:(NSOperationQueueCompletion)completion;

@end

NSOperationQueue + Completion.m

//
//  NSOperationQueue+Completion.m
//  QueueTest
//
//  Created by Artem Stepanenko on 23.11.13.
//  Copyright (c) 2013 Artem Stepanenko. All rights reserved.
//

#import "NSOperationQueue+Completion.h"

@implementation NSOperationQueue (Completion)

- (void)setCompletion:(NSOperationQueueCompletion)completion
{
    NSOperationQueueCompletion copiedCompletion = [completion copy];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self waitUntilAllOperationsAreFinished];

        dispatch_async(dispatch_get_main_queue(), ^{
            copiedCompletion();
        });
    });
}

@end

ব্যবহার :

NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    // ...
}];

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    // ...
}];

[operation2 addDependency:operation1];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation1, operation2] waitUntilFinished:YES];

[queue setCompletion:^{
    // handle operation queue's completion here (launched in main thread!)
}];

সূত্র: https://gist.github.com/artemstepanenko/7620471


কেন এটি একটি সমাপ্তি ? একটি NSOperationQueue সম্পূর্ণ হয় না - এটি নিছক খালি হয়ে যায়। NSOperationQueue এর জীবদ্দশায় খালি রাজ্যে বেশ কয়েকবার প্রবেশ করা যেতে পারে।
কাউচডেভোপার

যদি সেটকম্পশন বলা হওয়ার আগে ওপ 1 এবং অপ 2 সমাপ্ত হয় তবে এটি কাজ করে না।
মালহাল

দুর্দান্ত উত্তর, মাত্র 1 ক্যাভিয়েট যে ক্রিয়াকলাপটি সমস্ত ক্রিয়াকলাপ শুরু করার সাথে সাথে করা হয়ে গেলে সমাপ্তি ব্লকটি কল হয়। অপারেশন শুরু হচ্ছে! = অপারেশন সম্পূর্ণ।
সাকিব সৌদ

হুম পুরাতন উত্তর, কিন্তু আমি চাই বাজি waitUntilFinishedহওয়া উচিতYES
brandonscript

2

কিউওর ব্যবহার সারির operationCountসম্পত্তি পর্যবেক্ষণ করতে হবে ? তারপরে আপনি সারিটি খালি হয়ে গেলে এবং এটি খালি হওয়া বন্ধ করে দেওয়ার বিষয়ে শুনতে পেতেন। অগ্রগতি সূচকটি নিয়ে কাজ করা ঠিক যেমন কিছু করা ঠিক তত সহজ হতে পারে:

[indicator setHidden:([queue operationCount]==0)]

এই কাজ কি তোমার জন্য ছিল? আমার অ্যাপ্লিকেশনটিতে NSOperationQueue3.1 থেকে অভিযোগ করে যে এটি কীটির জন্য কেভিও-সম্মতিযুক্ত নয় operationCount
জুল

আমি আসলে কোনও অ্যাপ্লিকেশনে এই সমাধানটি চেষ্টা করে দেখিনি, না। ওপি করেছে কিনা তা বলতে পারছি না। তবে ডকুমেন্টেশনটি পরিষ্কারভাবে জানিয়েছে যে এটি কাজ করা উচিত । আমি একটি বাগ রিপোর্ট দায়ের করব। বিকাশকারী.এপল.
com

আইফোন এসডিকে (কমপক্ষে ৩.১.৩ হিসাবে নয়) এনএসপোপারেশনকুইয়েতে কোনও অপারেশনকন্ট সম্পত্তি নেই। আপনি অবশ্যই ম্যাক্স ওএস এক্স ডকুমেন্টেশন পৃষ্ঠাটি
নিক ফোরজ

4
সময় সমস্ত ক্ষত নিরাময় করে ... এবং কখনও কখনও ভুল উত্তরও দেয়। আইওএস 4 হিসাবে, operationCountসম্পত্তি উপস্থিত রয়েছে।
সিক্সটেন অটো

2

সর্বশেষ অপারেশনটি যুক্ত করুন:

NSInvocationOperation *callbackOperation = [[NSInvocationOperation alloc] initWithTarget:object selector:selector object:nil];

সুতরাং:

- (void)method:(id)object withSelector:(SEL)selector{
     NSInvocationOperation *callbackOperation = [[NSInvocationOperation alloc] initWithTarget:object selector:selector object:nil];
     [callbackOperation addDependency: ...];
     [operationQueue addOperation:callbackOperation]; 

}

4
যখন কাজগুলি একই সাথে সম্পাদন করা হয় তখন এটি ভুল পদ্ধতির।
মার্সিন

4
এবং সারিটি বাতিল হয়ে গেলে এই শেষ অপারেশনটি শুরু করা হয় না।
মালহাল

2

সঙ্গে ReactiveObjC আমি এই চমত্কারভাবে কাজ করে খুঁজে পেয়েছেন:

// skip 1 time here to ignore the very first call which occurs upon initialization of the RAC block
[[RACObserve(self.operationQueue, operationCount) skip:1] subscribeNext:^(NSNumber *operationCount) {
    if ([operationCount integerValue] == 0) {
         // operations are done processing
         NSLog(@"Finished!");
    }
}];

1

এফওয়াইআই, আপনি জিসিডি ডিসপ্যাচ_গ্রুপের সাথে সুইফট 3 এ অর্জন করতে পারেন । সমস্ত কাজ শেষ হয়ে গেলে আপনি বিজ্ঞপ্তি পেতে পারেন।

let group = DispatchGroup()

    group.enter()
    run(after: 6) {
      print(" 6 seconds")
      group.leave()
    }

    group.enter()
    run(after: 4) {
      print(" 4 seconds")
      group.leave()
    }

    group.enter()
    run(after: 2) {
      print(" 2 seconds")
      group.leave()
    }

    group.enter()
    run(after: 1) {
      print(" 1 second")
      group.leave()
    }


    group.notify(queue: DispatchQueue.global(qos: .background)) {
      print("All async calls completed")
}

এটি ব্যবহারের সর্বনিম্ন আইওএস সংস্করণটি কী?
নীতেশ বোরাড

এটি সুইফট 3, আইওএস 8 বা ততোধিকের থেকে উপলব্ধ।
অভিজিৎ

0

আপনি একটি নতুন তৈরি করতে পারেন NSThread, বা পটভূমিতে কোনও নির্বাচককে কার্যকর করতে পারেন এবং সেখানে অপেক্ষা করতে পারেন। NSOperationQueueশেষ হয়ে গেলে আপনি নিজের একটি বিজ্ঞপ্তি পাঠাতে পারেন।

আমি এরকম কিছু নিয়ে ভাবছি:

- (void)someMethod {
    // Queue everything in your operationQueue (instance variable)
    [self performSelectorInBackground:@selector(waitForQueue)];
    // Continue as usual
}

...

- (void)waitForQueue {
    [operationQueue waitUntilAllOperationsAreFinished];
    [[NSNotificationCenter defaultCenter] postNotification:@"queueFinished"];
}

থ্রেড তৈরি করার জন্য এটি কেবল ঘুমিয়ে রাখার জন্য কিছুটা নির্বোধ বলে মনে হচ্ছে।
কর্নেল

আমি রাজী. তবুও, আমি এর আশেপাশে আর কোনও উপায় খুঁজে পাইনি।
পিজিবি

আপনি কীভাবে নিশ্চিত করবেন যে কেবল একটি থ্রেড অপেক্ষা করছে? আমি পতাকা সম্পর্কে ভেবেছিলাম, তবে এটিকে জাতিগত অবস্থার বিরুদ্ধে রক্ষা করা দরকার এবং আমি আমার স্বাদের জন্য খুব বেশি এনএসলক ব্যবহার করে শেষ করেছি।
কর্নেল

আমি মনে করি আপনি NSOperationQueue অন্য কোনও বস্তুতে গুটিয়ে রাখতে পারেন। আপনি যখনই কোনও এনএসওপরেশন সারিবদ্ধ করেন, আপনি একটি সংখ্যা বৃদ্ধি করেন এবং একটি থ্রেড চালু করেন। যখনই কোনও থ্রেড শেষ হয় আপনি সেই সংখ্যাটি একে একে হ্রাস করুন। আমি এমন একটি দৃশ্যে ভাবছিলাম যেখানে আপনি আগে থেকে সমস্ত কিউ সারি করতে পারেন এবং তারপরে সারিটি শুরু করতে পারেন, সুতরাং আপনার কেবলমাত্র একটি অপেক্ষার থ্রেডের প্রয়োজন হবে।
পিজিবি

0

আপনি এই ব্যবহার করেন তাহলে অপারেশন আপনার বেস শ্রেণী হিসেবে, আপনি পাস পারে whenEmpty {}অবরোধ OperationQueue :

let queue = OOperationQueue()
queue.addOperation(op)
queue.addOperation(delayOp)

queue.addExecution { finished in
    delay(0.5) { finished() }
}

queue.whenEmpty = {
    print("all operations finished")
}

4
'অপারেশনকিউ'র ধরণের মানটির কোনও সদস্য নেই' কখনই '
ডেল

@ ডেল আপনি যদি লিঙ্কটিতে ক্লিক করেন তবে এটি আপনাকে গিথুব পৃষ্ঠায় নিয়ে যাবে যেখানে সমস্ত কিছু ব্যাখ্যা করা আছে। যদি আমি সঠিকভাবে স্মরণ করি তবে উত্তরটি যখন ফাউন্ডেশনের অপারেশনকুইউটিকে এখনও এনএসপিটারেশনকিউ বলা হত; সুতরাং সেখানে অস্পষ্টতা কম ছিল।
ব্যবহারকারী 1244109

আমার খারাপ ... আমি ভ্রান্ত সিদ্ধান্তে পৌঁছেছি যে উপরে "অপারেশনকিউ" সুইফট 4 এর "অপারেশনকিউ" ছিল।
ডেল

0

কেভিও ছাড়াই

private let queue = OperationQueue()

private func addOperations(_ operations: [Operation], completionHandler: @escaping () -> ()) {
    DispatchQueue.global().async { [unowned self] in
        self.queue.addOperations(operations, waitUntilFinished: true)
        DispatchQueue.main.async(execute: completionHandler)
    }
}

0

আপনি যদি এখানে কম্বাইনের সাহায্যে সমাধান খুঁজছেন - আমি কেবল আমার নিজের রাষ্ট্রের অবজেক্ট শুনে এসেছি।

@Published var state: OperationState = .ready
var sub: Any?

sub = self.$state.sink(receiveValue: { (state) in
 print("state updated: \(state)")
})
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.