将Objective-C块存储在std ::功能中是安全的吗?



我想将回调块从我的Objective-C 代码传递到C 对象。这非常简单,因为我能够为std ::函数分配一个块。在我的迷你示例中,一切都很好,但是我仍然不确定是否可以安全。

#import "ViewController.h"
#include <functional>
std::function<void(void)> f;

@interface T : NSObject
@property (strong) NSString* value;
@end
@implementation T
- (void)dealloc {
    NSLog(@"dealloc");
}
@end

@implementation ViewController

- (IBAction)storeBlock:(UIButton *)sender {
    T* t = [[T alloc] init];
    t.value = @"the captured obj";
    f = ^void(void) { NSLog(@"This is the block with %@", t.value); };
}
- (IBAction)useBlock:(UIButton *)sender {
    f();
}
- (IBAction)releaseBlock:(UIButton *)sender {
    f = nullptr;
}

@end

我已经了解到,如果我想超越块的创建范围,我必须将块存储在堆栈上,并且必须将其复制到堆中(我在示例中尚未明确地使用它(。我也不确定弧如何处理这种情况。是否允许"官方"这样做?我正在使用Xcode 9.2。

Objective-C块在执行范围定义的范围时变得无效。为了避免这种情况,必须在块上使用复制方法,仅此而已。

块被视为正常对象,尽管事实是他们在堆栈上开始生命。就像您说的那样,在OBJC-CPP中,我们可以轻松地将一个块存储在std ::函数: - (

那么,您的示例会发生什么?您将std ::函数" F"声明为全局堆栈对象。将块分配给该块时,从块对象分配了参考计数为1。在放在板块函数的" t" - 对象上,请在其上留下两个参考之前。一个是" t",一个通过块中的捕获机构。离开示波器,仅保留块参考。然后" f"设置为nullptr:没有对块对象的引用 ->块被交易,然后用它为" t" -object,因为它都不指向它。

最新更新