使用外部NSThread

时间:2016-02-09 19:46:09

标签: objective-c multithreading swift macos

我已经编写了一个类似于Grand Central Dispatch的类,它将对要在线程池上执行的块进行排队。 (为什么你想知道?因为我需要一个具有线程亲和力的GCD。)

代码非常简单:

static let sharedInstance=CuprumOperationQueue()

func addOperation(operation: ()->()) {
    dispatch_async(_operationsQueue) {
        //Place the operation on the queue
        self._operations.append(operation)
        dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) {
            self.pushQueue()
        }
    }
}

func getOperation() -> ClosureType? {
    var operation: ClosureType?=nil;

    dispatch_sync(_operationsQueue) {
        if (!self._operations.isEmpty) {
            operation=self._operations.removeFirst();
        }
    }

    return operation;
}

func pushQueue() {
    for thread in _threads {
        if (CFRunLoopIsWaiting(thread.runLoop)) {
            if let operation = self.getOperation() {
                CFRunLoopPerformBlock(thread.runLoop, kCFRunLoopDefaultMode, operation); //(2)
                CFRunLoopWakeUp(thread.runLoop);
            } else {
                //There are no more operations to perform
                break;
            }
        }
    }
}

我使用GCD串行队列(_operationsQueue)来序列化对块(_operations)的数组访问。当运行循环即将休眠时,线程(使用观察者运行CFRunLoop)调用pushQueue。

我按如下方式使用队列:

[[CuprumOperationQueue sharedInstance] addOperation:^{ //(1)
        [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) {
            NSLog(@"test %p",self);
        }];
}];

问题是调用上述代码段的对象永远不会被释放。它没有被报告为仪器中的泄漏,因此至少有一些可达参考。我只是不知道在哪里。我怀疑某处有一个保留周期,因为从NSLog语句中删除自引用会导致该对象被释放。但这不是整个问题,因为使用NSOperationQueue替换等效线(1)也会导致对象被正确释放(即使在第二个块中使用自引用)。因此,只有与我的自定义队列结合才会出现问题。

如果在基于Swift的队列类中,我删除了带有(2)的行上的调用,该对象也被正确释放。

正如您所看到的,没有多少代码可以导致问题,但我真的不知道这可能会导致保留周期。

任何见解都将受到高度赞赏。

0 个答案:

没有答案