【发布时间】:2015-06-18 00:43:13
【问题描述】:
有没有办法指定特定方法参数的语义较弱?
详细来说,这是一个按预期工作的 Objective-C 示例代码:
- (void)runTest {
__block NSObject *object = [NSObject new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self myMethod:object];
});
// to make sure it happens after `myMethod:` call
dispatch_async(dispatch_get_main_queue(), ^{
object = nil;
});
}
- (void)myMethod:(__weak id)arg0 {
NSLog(@"%@", arg0); // <NSObject: 0x7fb0bdb1eaa0>
sleep(1);
NSLog(@"%@", arg0); // nil
}
这是 Swift 版本,不是
public func runTest() {
var object: NSObject? = NSObject()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
self.myMethod(object)
}
dispatch_async(dispatch_get_main_queue()) {
object = nil
}
}
private func myMethod(arg0: AnyObject?) {
println("\(arg0)") //Optional(<NSObject: 0x7fc778f26cf0>)
sleep(1)
println("\(arg0)") //Optional(<NSObject: 0x7fc778f26cf0>)
}
我是否正确假设在 Swift 版本中的方法调用之间 arg0 无法变为 nil ? 谢谢!
更新一位来自 Apple Dev.Forums 的用户指出 sleep 不是一个好用的函数,连续的分派可能会导致竞争条件。虽然这些可能是合理的担忧,但这只是一个示例代码,问题的重点是传递弱参数。
【问题讨论】:
-
目前不可能,您可以在 Swift 2.0 之前使用
[weak yourObject]在关闭开始时这样做。另请参阅here,其中显示了一些解决方法 -
我知道弱闭包可能是一种解决方案,但它并不能解决问题,我不希望 API 的所有消费者都知道我的实现细节。不过在 Swift 2 中有可能吗?
-
消费者如何知道你的 API 实现是这样的?
-
因为在函数签名中封装弱语义似乎是不可能的,这意味着我的 API 的使用者将始终需要注意传递弱引用。否则,我将在函数体的生命周期内延长传递参数的生命周期
-
为什么你认为第二个 dispatch_async 调用发生在 myMethod: 被调用之前?可能,是的 - 保证?不,我想。
标签: swift arguments automatic-ref-counting weak-references