objective-c - 同步块(synchronized block)内的 block ?

标签 objective-c closures objective-c-blocks

我正在研究 Objective-C 中的 block ,试图提出一种可重用的机制,该机制将采用任意代码块和一个锁对象,然后在新线程上执行该代码块,并在提供锁。我们的想法是想出一种简单的方法来将所有同步开销/等待移出主线程,以便应用程序的 UI 始终具有响应能力。

我想出的代码非常简单,如下所示:

- (void) executeBlock: (void (^)(void))block {
    block();
}

- (void) runAsyncBlock: (void (^)(void))block withLock:(id)lock {
    void(^syncBlock)() = ^{
        @synchronized(lock) {
            block();
        }
    };
    [self performSelectorInBackground:@selector(executeBlock:) withObject:syncBlock];
}

例如,您可能有一些类似的方法:

- (void) addObjectToSharedArray:(id) theObj {
    @synchronized(array) {
        [array addObject: theObj];
    }
}

- (void) removeObjectFromSharedArray:(id) theObj {
    @synchronized(array) {
        [array removeObject: theObj];
    }
}

这工作正常,但在等待锁时会阻塞调用线程。这些可以重写为:

- (void) addObjectToSharedArray:(id) theObj {
    [self runAsyncBlock:^{
        [array addObject: theObj];
    } withLock: array];
}

- (void) removeObjectFromSharedArray:(id) theObj {
    [self runAsyncBlock: ^{
        [array removeObject: theObj];
    } withLock:array];
}

它应该总是立即返回,因为只有后台线程会竞争锁。

问题是,这段代码在 executeBlock: 之后崩溃,没有产生任何输出、错误消息、崩溃日志或任何其他有用的东西。我的方法有什么根本性的缺陷吗?如果没有,关于为什么这可能会崩溃有什么建议吗?

编辑:

有趣的是,如果我这样做,它就不会崩溃:

- (void) runAsyncBlock: (void (^)(void))block withLock:(id)lock {
    void(^syncBlock)() = ^{
        @synchronized(lock) {
            block();
        }
    };
    syncBlock();
}

但是这当然会阻塞调用线程,这在很大程度上违背了目的。 block 有可能不跨越线程边界吗?我认为不会,因为这很大程度上会违背最初拥有它们的目的。

最佳答案

记住调用[block copy],否则它不会正确保留,因为 block 是在堆栈上创建的,并在退出范围时销毁,除非您调用copy,否则它不会移动甚至调用 retain 来堆。

- (void) runAsyncBlock: (void (^)(void))block withLock:(id)lock {
    block = [[block copy] autorelease];
    void(^syncBlock)() = ^{
        @synchronized(lock) {
            block();
        }
    };
    syncBlock = [[syncBlock copy] autorelease];
    [self performSelectorInBackground:@selector(executeBlock:) withObject:syncBlock];
}

关于objective-c - 同步块(synchronized block)内的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8906026/

相关文章:

objective-c - 自定义基于 View 的 nstableview 调整大小

ios - 我正确使用这个 block 吗?

iOS:如果我将 View Controller 实例传递给 dispatch_async block ,它不会被释放

javascript - 带函数的 JavaScript 闭包是如何工作的?

Clojure、闭包、WebSocket、在线聊天演示

Javascript 函数(来自闭包)

iphone - map 套件 :How to add annotation on MKLocalSearch results placemarks?

ios - AFNetworking 500响应主体

objective-c - 重命名连接的 Action

ios - 如何在没有 Mac Developer 程序成员(member)资格的情况下使用 NSLogger Desktop Client