标签: nsoperationqueue

如何从NSOperationQueue中删除/取消NSInvocationOperation?

在上下文中要求以下两个问题来维护NSOperationQueue和NSInvocationOperation.

由于我使用此概念下载多个视频,如何在完成下载视频后从NSOperationQueue中删除/释放添加的NSInvocationOperation?

而且,如果我想在下载过程中停止下载特定视频,我该怎么办?

iphone multithreading nsoperationqueue nsinvocation

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

从 NSOperationQueue 取消 NSOperation 导致崩溃


我正在尝试构建一个下载管理器类,它将所有异步下载(每个操作都有自己的线程)操作打包到 NSOperation 子类中,以便稍后将它们添加到 NSOperationQueue 中。下载管理器类(单例)还公开了一些方法来处理队列并取消符合某些要求的操作。
这些是开始创建类集群(抽象工厂)的步骤,该类集群为不同类型的常见操作(上传、下载、解析等)返回不同类型的 NSOperation。
该类似乎可以很好地处理下载操作,但如果在这些操作中间我调用取消操作的方法,则该操作会成功取消,但应用程序会在稍后的几个操作中崩溃。如果我不取消任何操作,一切都会正常。所有操作均使用 KVO 进行观察。删除操作的方法如下所示:

- (void) cancelDownloadOperationWithID:(NSString *)aUUID{
@synchronized(self){
    [self.dowloadQueue setSuspended:YES]; //downloadQueue is an NSOperationQueue
    NSArray * downloadOperations = [self.dowloadQueue operations];
    NSPredicate * aPredicate = [NSPredicate predicateWithFormat:@"SELF.connectionID == %@",aUUID]; //SELF is the signleton instance of the download manager
    NSArray * filteredArray = [downloadOperations filteredArrayUsingPredicate:aPredicate];
    if ([filteredArray count]==0) {
        [self.dowloadQueue setSuspended:NO];
        return;
    } 
    [filteredArray makeObjectsPerformSelector:@selector(cancel)];
    NSLog(@"Cancelled %d operations",[filteredArray count]);
    [self.dowloadQueue setSuspended:NO];
   }
}
Run Code Online (Sandbox Code Playgroud)

崩溃日志非常难以理解,但是是一个 BAD_EXC_ACCESS (可能是僵尸),请注意我处于 ARC 下。

0x00a90ea8  <+0393>  jle    0xa90d9f <____NSOQSchedule_block_invoke_0+128>
0x00a90eae  <+0399> …
Run Code Online (Sandbox Code Playgroud)

iphone download nsoperation nsoperationqueue ios

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

NSOperationQueue 的 addOperation: 操作已完成无法入队?

注意:
这只是一个概念验证。
真正的后台任务是不断请求原始数据的“HTTP Get”并通过主线程显示;一经请求。

场景:
1)按需切换后台任务(循环)。
2) 后台任务在每次迭代时通知主线程 UI。
3) 只有一 (1) 个块操作在队列中运行。

Modus Operandus
1) 使用 NSBlockOperation 来包含后台代码。
2)使用区域BOOL来切换循环;通过 IBAction。

问题
1) 编译器将 BOOL 'isRunning' 标记为链接:

在此块中强烈捕获“自我”可能会导致保留循环。


2)在尝试添加块操作之前,我检查了队列中是否有任何操作。
但我总是收到以下错误:

-[NSOperationQueue addOperation:]: 操作完成,不能入队

除了上述问题之外,这种概念验证似乎正在发挥作用。

问题:
1) 为什么编译将 BOOL 'running' 标记为一个强行,而它只是一个缩放器?
2)如果在队列中没有找到,为什么我不能通过添加另一个 NSBlockOperation 来重用 NSOperationQueue?

以下是整个代码:

#define START 0
#define STOP 1

@interface ricViewController ()
@property (assign) BOOL running;
@end

@implementation ricViewController {
    NSOperationQueue *operationQueue;
    NSBlockOperation *blockOperation;
    void (^backgroundBlock)(void);
}

@synthesize running = isRunning;

#pragma mark - ViewController methods …
Run Code Online (Sandbox Code Playgroud)

objective-c nsoperationqueue ios nsblockoperation cloudkit

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

NSOperation 已准备就绪但未在 iOS 7 上启动

我们创建了一个操作框架来添加一些在基类中没有的功能(例如跟踪成功/失败)。父操作通常是非并发的,可能只是为了管理子操作而存在。通常并发的子操作(异步下载 xml 和媒体)。

当我们在 iOS 7 上运行我们的应用程序时,将一些操作添加到操作队列中,大约有 3/4 的操作完成,然后应用程序似乎挂起。

当我在调试器中暂停应用程序,并检查队列中的操作 (sOpQueue.operations) 时,其中许多已准备好运行(isReady 返回 TRUE),但显然它们都没有执行(isExecuting 返回 FALSE,而我看不到任何线程上运行的任何操作的证据)。

这是 iOS 7 的新问题。

当我增加或减少并发操作的数量时,行为似乎没有改变。

有没有人对如何确定未启动就绪操作的原因有任何建议?

谢谢,查克

nsoperation nsoperationqueue ios

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

使用 maxConcurrentOperationCount 的 NSOperationQueue 单元测试

我有一个类,它是NSOperationQueue. 它允许使用块对网络请求进行排队。目前,请求是一个接一个执行的,但这种情况将来可能会改变。

这是 MyRequestsQueue 类的代码:

@interface MyRequestsQueue ()

@property(nonatomic, strong) NSOperationQueue* queue;

@end

@implementation MyRequestsQueue

-(instancetype)init
{
    self = [super init];
    if(!self) {
        return nil;
    }

    self.queue = [[NSOperationQueue new] autorelease];
    self.queue.maxConcurrentOperationCount = 1;

    return self;
}

-(void)addRequestBlock:(void (^)())request
{
    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:request];
    [self.queue addOperation:operation];
}

@end
Run Code Online (Sandbox Code Playgroud)

一般来说,我知道如何使用 XCTest 对异步代码进行单元测试。但现在我想添加一个单元测试来MyRequestsQueue检查队列当时是否只执行一个操作。或者甚至更好 - 测试当前正在执行的操作的数量不大于maxConcurrentOperationCount。我试图观察operationCount的属性self.queue,但文档说我不应该依赖它。我怎样才能实现它?

编辑:我的测试使用以下模式:

@interface MessageRequestQueueTest : XCTestCase

@property(nonatomic, strong) MessageRequestsQueue* reuqestQueue;
@property(nonatomic, assign) NSInteger finishedRequestsCounter;

@end …
Run Code Online (Sandbox Code Playgroud)

unit-testing objective-c nsoperationqueue ios xctest

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

NSOperationQueue:在超时给定后取消操作

基本上,如果我添加到队列的操作在某个超时后没有响应,我想执行取消:

NSOperationQueue *   queue = ...

[self.queue addOperationWithBlock:^{
        // my block...
    } timeoutInSeconds:5.0 hasTimedOutWithBlock:^{
        // called after 5.0, operation should be canceled at the end
}];
Run Code Online (Sandbox Code Playgroud)

多谢你们 !

asynchronous objective-c nsoperation nsoperationqueue ios

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

如何等待所有NSOperations完成?

我有以下代码:

func testFunc(completion: (Bool) -> Void) {
    let queue = NSOperationQueue()
    queue.maxConcurrentOperationCount = 1

    for i in 1...3 {
        queue.addOperationWithBlock{
            Alamofire.request(.GET, "https://httpbin.org/get").responseJSON { response in
                switch (response.result){
                case .Failure:
                    print("error")
                    break;
                case .Success:
                    print("i = \(i)")
                }
            }
        }
        //queue.addOperationAfterLast(operation)
    }
    queue.waitUntilAllOperationsAreFinished()
    print("finished")
}
Run Code Online (Sandbox Code Playgroud)

输出是:

finished
i = 3
i = 1
i = 2
Run Code Online (Sandbox Code Playgroud)

但我希望以下内容:

i = 3
i = 1
i = 2
finished
Run Code Online (Sandbox Code Playgroud)

那么,为什么queue.waitUntilAllOperationsAreFinished()不等待?

nsoperation nsoperationqueue ios swift

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

NSOperationQueue快速完成所有任务3

我正在尝试实现NSOperationQueue完成swift 3中的所有任务操作.我创建了一个下面的演示代码,它正在按照我的期望工作.

func downloadTopStroiesDetails(){
    let operationQueue: OperationQueue = OperationQueue()
    let operation1 = BlockOperation() {
         print("BlockOperation1")
        for id in 0...5{
            operationQueue.addOperation(downloadArticle(index: id))
        }
        let operation2 = BlockOperation() {
            print("BlockOperation2")
        }
        operationQueue.addOperation(operation2)
    }
    operationQueue.addOperation(operation1)
}

func downloadArticle(index:Int) -> Operation {
    let operation: Operation = BlockOperation { () -> Void in
        print(index)
    }
    return operation
}
downloadTopStroiesDetails() // start calling 
Run Code Online (Sandbox Code Playgroud)

输出:

BlockOperation1
0
1
2
3
4
5
BlockOperation2
Run Code Online (Sandbox Code Playgroud)

但是当我在下载文章中使用Alamofire调用Web API时,方法输出是不同的.

func downloadArticle(index:Int) -> Operation {
        let operation = BlockOperation(block: {
            RequestManager.networkManager.fetchFromNetworkwithID(articleid: index) …
Run Code Online (Sandbox Code Playgroud)

nsoperation nsoperationqueue ios swift

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

为什么操作队列中不需要[weak self]或[unowned self]?

在了解了Swift 的捕获列表以及如何使用它来避免保留循环之后,我不禁注意到一些令人费解的事情OperationQueue:它不需要[weak self]或 来[unowned self]防止内存泄漏。

class SomeManager {
    let queue = OperationQueue()
    let cache: NSCache = { () -> NSCache<AnyObject, AnyObject> in
        let cache = NSCache<AnyObject, AnyObject>()
        cache.name = "huaTham.TestOperationQueueRetainCycle.someManager.cache"
        cache.countLimit = 16
        return cache
    }()

    func addTask(a: Int) {
        queue.addOperation { // "[unowned self] in" not needed?
            self.cache.setObject(a as AnyObject, forKey: a as AnyObject)
            print("hello \(a)")
        }
    }
}

class ViewController: UIViewController {

    var someM: SomeManager? = SomeManager()

    override func viewDidLoad() …
Run Code Online (Sandbox Code Playgroud)

memory-leaks nsoperationqueue automatic-ref-counting retain-cycle swift

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

NSOperationQueue在响应iOS上再次运行相同的任务

在我的项目中,我需要将数据发送到服务器,为此我使用以下代码来完成任务:

- (void)sendJSONToServer:(NSString *) jsonString
{
// Create a new NSOperationQueue instance.
operationQueue = [NSOperationQueue new];
//

// Create a new NSOperation object using the NSInvocationOperation subclass to run the operationQueueTask method
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(operationQueueTask:)
                                                                        object:jsonString];
// Add the operation to the queue and let it to be executed.
[operationQueue addOperation:operation];
}//End of sendJSONToServer method

-(void) operationQueueTask:(NSString *) jsonString
{
//NSOperationQueue *remoteResultQueue = [[NSOperationQueue alloc] init];
dispatch_queue_t myQueue = dispatch_queue_create("SERVER_QUEUE",NULL);
dispatch_async(myQueue, ^{
    // Performing long running …
Run Code Online (Sandbox Code Playgroud)

iphone nsoperation nsoperationqueue ios

2
推荐指数
1
解决办法
1696
查看次数