标签: nsoperationqueue

为什么NSOperationQueue在主线程上处理大量任务时比GCD或performSelectorOnMainThread更快?

例如,我有100次for循环.并且需要更新UIImageView,最后2个方法慢慢相同.为什么?他们之间有什么不同?

//fastest
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                       [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
                        [scrollView addSubview:btnThumb];
                   }];
//slowly
                     dispatch_async(dispatch_get_main_queue(), ^
                    {
                        [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
                        [scrollView addSubview:btnThumb];
                    });       
//slowly
                   [btnThumb setImage:[UIImage imageWithData:data] forState:UIControlStateNormal];
                   [self performSelectorOnMainThread:@selector(testMethod:) withObject:[NSArray arrayWithObjects:scrollView, btnThumb, nil] waitUntilDone:NO];

    -(void) testMethod:(NSArray*)objs
    {

        UIScrollView *scroll = [objs objectAtIndex:0];
        UIButton *btn = [objs lastObject];
        [scroll addSubview:btn];
    }
Run Code Online (Sandbox Code Playgroud)

multithreading nsoperationqueue grand-central-dispatch ios

4
推荐指数
1
解决办法
1132
查看次数

[NSOperationQueue mainQueue]是否保证是连续的?

也就是说,如果我们几次排队同样的事情就不会有并发性.我们首先排队的那个将首先被执行.

我的意思是只有一个主线程对吗?

objective-c nsoperationqueue ios xcode4.5

4
推荐指数
1
解决办法
2775
查看次数

NSOperation 依赖和completionBlock

我们有一个关于 NSOperationQueue 的简单问题,这是一个简单的操作逻辑:

self.queue = [[NSOperationQueue alloc] init];

NSOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"- Running operation A");
    [NSThread sleepForTimeInterval:1.2];
    NSLog(@"- Done operation A");
}];

NSOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"- Running operation B");
    [NSThread sleepForTimeInterval:2];
    NSLog(@"- Done operation B");
}];

[operationA setCompletionBlock:^{
    NSLog(@"-- Completion Block A");
}];

[operationB setCompletionBlock:^{
    NSLog(@"-- Completion Block B");
}];

[operationB addDependency:operationA];
[self.queue addOperations:@[operationA, operationB] waitUntilFinished:NO];
Run Code Online (Sandbox Code Playgroud)

这是最终的输出

2015-12-21 14:59:57.463 SampleProject[18046:310901] - Running operation A
2015-12-21 14:59:58.664 SampleProject[18046:310901] - Done operation A
2015-12-21 14:59:58.664 SampleProject[18046:310900] - Running …
Run Code Online (Sandbox Code Playgroud)

objective-c nsoperation nsoperationqueue

4
推荐指数
1
解决办法
1306
查看次数

如何确保OperationQueue中的操作一个接一个地完成

当执行彼此依赖的操作时,OperationQueue可以使用它们来确保它们以正确的顺序执行.但是,是否也可以确保操作一个接一个地完成?

让我们假设一个异步执行的方法,需要一些时间才能完成:

public func performOperation(_ number: Int, success: @escaping (Int) -> Void)->Void {
        DispatchQueue(label: "operations").async {
            print("Operation #\(number) starts")
            usleep(useconds_t(1000-number*200)) // Block thread for some time
            success(number)
        }
}
Run Code Online (Sandbox Code Playgroud)

操作和依赖关系创建如下:

let operationQueue = OperationQueue.main
for operationNumber in 0..<4 { // Create operations as an example
    let operation = BlockOperation(block: {
        performOperation(operationNumber) { number in
            DispatchQueue.main.sync {
                print("Operation #\(number) finished")
            }
        }
    })
    operation.name = "Operation #\(operationNumber)"

    if operationNumber > 0 {
        operation.addDependency(operationQueue.operations.last!)
        // Print dependencies
        print("\(operation.name!) should finish …
Run Code Online (Sandbox Code Playgroud)

concurrency nsoperation nsoperationqueue ios swift

4
推荐指数
1
解决办法
3560
查看次数

iOS - 后台进程和UI更新

问题很简单:我的应用程序控制每次启动时是否有更新.如果有更新,弹出窗口将显示是或否选择.当用户点击是4方法开始.这些方法下载xml文件并上传CoreData.这是警报的代码:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex==1) {
        [self showActivityViewer];
        [self downloadControlAndUpdatePoi];
        [self downloadControlAndUpdateItinerari];
        [self downloadControlAndUpdateArtisti];
        [self downloadControlAndUpdateEventi];
        [self hideActivityViewer];
        NSLog(@"AGGIORNA");
    } else {
        NSLog(@"NON AGGIORNARE");
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是有一个问题:当用户点击是时,警报不会消失并保留在屏幕上,直到所有方法都完成.所以我尝试这个其他代码:

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    if (buttonIndex==1) {
        [self showActivityViewer];
        [NSThread detachNewThreadSelector:@selector(startDownloads) toTarget:self withObject:nil];
        [self hideActivityViewer];
        NSLog(@"AGGIORNA");
    } else {
        NSLog(@"NON AGGIORNARE");
        return;
    }
}

-(void)startDownloads {
    NSInvocationOperation *opPoi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdatePoi) object:nil];
    NSInvocationOperation *opItinerari=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateItinerari) object:nil];
    NSInvocationOperation *opArtisti=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateArtisti) object:nil];
    NSInvocationOperation *opEventi=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadControlAndUpdateEventi) object:nil]; …
Run Code Online (Sandbox Code Playgroud)

background nsoperation nsthread nsoperationqueue ios

3
推荐指数
1
解决办法
4950
查看次数

主线程上的NSFetchedResultsController忽略从另一个线程保存到Core Data?

我有一个NSFetchedResultsController主线程.同样从主线程,我异步发送JSON的网络请求.当JSON字符串返回时,我启动NSOperation一个新的(后台)NSManagedObjectContext,解析JSON字符串,创建/更新NSManagedObject,并将它们保存在上下文中.后台上下文与主上下文具有相同的persistentStore.有了这个,我有两个问题:

  1. 我认为从任何上下文(在任何线程上)对持久性存储的任何保存都会通知主要NSFetchedResultsController有变化,但到目前为止它没有发现任何变化.我应该做些什么来通知主线程NSFetchedResultsController有外部save的,以便相应的tableView更新?

  2. 因此,在主线程上,我订阅NSManagedObjectContextWillSaveNotification并正确查看所有上下文(包括完全在单独线程上存在的上下文)何时执行save操作.的苹果文档说的是notification.userInfo具有应3个阵列,一个阵列的每个在后台线程的"更新,删除和插入的"模型对象的字典.但是,这对我userInfo来说总是如此nil.我有什么想法我做错了吗?

订阅NSManagedObjectContextWillSaveNotificationAppDelegate:

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(managedObjectContextDidSave:)
                                             name:NSManagedObjectContextWillSaveNotification 
                                           object:nil];
Run Code Online (Sandbox Code Playgroud)

以及在AppDelegate中保存上下文的方法:

- (void)managedObjectContextDidSave:(NSNotification *)notification {
    DLog(@"notification: %@", notification); //not nil
    DLog(@"notification user info: %@", notification.userInfo); // always nil... why??

    NSManagedObjectContext *theContext = notification.object;
    if(theContext != context) {
        DLog(@"---- SAVED ON ANOTHER CONTEXT");

        // should I notify NSFetchedResultsController that there were …
Run Code Online (Sandbox Code Playgroud)

multithreading core-data nsfetchedresultscontroller nsoperationqueue nsmanagedobjectcontext

3
推荐指数
1
解决办法
1338
查看次数

AFNetworking setUploadProgressBlock行为不直接达到100%

我正在使用AFNetworking Framework来帮助将照片上传到网站.上传工作正常,但我需要在UIProgressView中显示进度.问题是,在上传开始后,进度从0到100%左右移动,并且在一段时间内保持100%,具体取决于上传的照片数量.我使用一个请求一次上传1到6张照片.关于这里发生了什么的任何想法?AFNetworking不包括照片的大小吗?
它在NSLOG中正确显示:

2012-04-03 10:49:45.498 PhotoUp[3689:2207] Sent 32768 of 217931 bytes
2012-04-03 10:49:45.499 PhotoUp[3689:2207] Sent 65536 of 217931 bytes
2012-04-03 10:49:45.501 PhotoUp[3689:2207] Sent 98304 of 217931 bytes
2012-04-03 10:49:45.502 PhotoUp[3689:2207] Sent 131072 of 217931 bytes
2012-04-03 10:49:47.795 PhotoUp[3689:2207] Sent 134310 of 217931 bytes
2012-04-03 10:49:49.070 PhotoUp[3689:2207] Sent 136730 of 217931 bytes
2012-04-03 10:49:50.819 PhotoUp[3689:2207] Sent 139150 of 217931 bytes
2012-04-03 10:49:52.284 PhotoUp[3689:2207] Sent 141570 of 217931 bytes
Run Code Online (Sandbox Code Playgroud)

这是代码:

NSString *numberOfPhotosAsString = [NSString stringWithFormat:@"%d", numberOfPhotos];


NSString *fileBase = @"file0_";
NSString *fileNameBase …
Run Code Online (Sandbox Code Playgroud)

nsoperation uiprogressview nsoperationqueue ios afnetworking

3
推荐指数
1
解决办法
3995
查看次数

并发操作,NSOperationQueue和异步API需要澄清

这是一个两部分问题.希望有人可以回答完整的答案.

NSOperations是强大的对象.它们可以是两种不同的类型:非并发或并发.

第一种类型同步运行.您可以通过将非并发操作添加到a中来利用它们NSOperationQueue.后者为您创建一个线程.结果包括以并发方式运行该操作.唯一需要注意的是这种操作的生命周期.当其main方法完成时,它将从队列中删除.处理异步API时,这可能是一个问题.

现在,并发操作呢?来自Apple doc

如果要实现并发操作(即,相对于调用线程异步运行的操作),则必须编写其他代码以异步启动操作.例如,您可能会生成一个单独的线程,调用异步系统函数或执行任何其他操作以确保start方法启动任务并立即返回,并且很可能在任务完成之前返回.

这对我来说几乎是清楚的.它们以异步方式运行.但是你必须采取适当的行动来确保他们这样做.

我不清楚的是以下内容.Doc说:

注意:在OS X v10.6中,操作队列忽略isConcurrent返回的值,并始终从单独的线程调用操作的start方法.

它的真正含义是什么?如果我在一个并发操作中会发生NSOperationQueue什么?

然后,在此并发操作中,并发操作用于通过NSURLConnection(以其异步形式)下载某些HTTP内容.操作是并发的并包含在特定队列中.

UrlDownloaderOperation * operation = [UrlDownloaderOperation urlDownloaderWithUrlString:url];
[_queue addOperation:operation];
Run Code Online (Sandbox Code Playgroud)

由于NSURLConnection需要循环运行,作者start在主线程中分流方法(所以我想将操作添加到它产生不同的队列的队列中).以这种方式,主运行循环可以调用操作中包含的委托.

- (void)start
{
    if (![NSThread isMainThread])
    {
        [self performSelectorOnMainThread:@selector(start) withObject:nil waitUntilDone:NO];
        return;
    }

    [self willChangeValueForKey:@"isExecuting"];
    _isExecuting = YES;
    [self didChangeValueForKey:@"isExecuting"];

    NSURLRequest * request = [NSURLRequest requestWithURL:_url];
    _connection = [[NSURLConnection alloc] initWithRequest:request
                                                  delegate:self];
    if (_connection == nil)
        [self finish];
}

- (BOOL)isConcurrent
{ …
Run Code Online (Sandbox Code Playgroud)

asynchronous objective-c nsoperation nsoperationqueue ios

3
推荐指数
1
解决办法
1749
查看次数

将NSOperationQueue添加到NSOperation

是否可以安全地添加NSOperationQueue到一个NSOperation,然后将此操作添加到另一个NSOperationQueue

这里有一些代码可视化我想要做的事情.

NSOperationQueue *mainQueue = [NSOperationQueue alloc] init];

// Here I declare some NSBlockOperation's, i.e. parseOperation1-2-3
// and also another operation called zipOperation, which includes
// an NSOperationQueue itself. This queue takes the processed (parsed) files
// and write them to a single zip file. Each operation's job is to write the data
// stream and add it to the zip file. After all operations are done,
// it closes the zip.

[zipOperation addDependency:parseOperation1]; …
Run Code Online (Sandbox Code Playgroud)

objective-c nsoperation nsoperationqueue

3
推荐指数
1
解决办法
1134
查看次数

如何在swift 4中进行两个并发API调用

在此先感谢您的帮助,我有两个API调用,两个都是并发的,任何调用都可以先成功(我不想按顺序调用),两个调用成功后,我必须停止我的活动指示器并重新加载我的tableView ,这是我的代码,但我不知道这是否正确以及如何重新加载我的tableView并停止我的活动指示器.

func downloadDetails(){
    let operationQueue: OperationQueue = OperationQueue()
    let operation1 = BlockOperation() {
    WebServiceManager.getAData(format:A, withCompletion: {(data: Any? , error: Error?) -> Void in

          if let success = data {
              DispatchQueue.main.async {
                  (success code)
              }
           }
        })

        let operation2 = BlockOperation() {
        webServiceManager.getBData(format: B, withCompletion: {(data: Any? , error: Error?) -> Void in

                if let success = data {
                    DispatchQueue.main.async {
                       (success code)
                    }
                }
            })
        }
        operationQueue.addOperation(operation2)
    }
    operationQueue.addOperation(operation1)
}
downloadDetails() "calling function"
Run Code Online (Sandbox Code Playgroud)

nsoperation nsoperationqueue ios swift4 swift4.1

3
推荐指数
1
解决办法
3824
查看次数