gpt4 book ai didi

swift - 弱方法参数语义

转载 作者:搜寻专家 更新时间:2023-10-30 22:06:01 24 4
gpt4 key购买 nike

有没有办法指定特定方法参数具有弱语义?

具体来说,这是一个按预期工作的 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>)
}

我在 ym 假设中是否正确,即在 Swift 版本的方法调用之间 arg0 无法变为 nil?谢谢!

更新 一位来自 Apple Dev.Forums 的用户指出 sleep 不是一个好用的函数,连续调度可能会导致竞争条件。虽然这些担忧可能是合理的,但这只是示例代码,问题的重点是传递弱参数。

最佳答案

Swift 没有“weak args”……但这可能只是因为 Swift (3.0) args 是不可变的(等同于 lets)和 Swift 中的 weak 东西需要同时是 varOptional

也就是说,确实有一种非常简单的方法可以实现与弱参数等效的方法——使用 weak var local (释放要释放的 arg-var)。这是可行的,因为 Swift 直到当前作用域结束才挂起 vars(就像 C++ 那样严格);而是它在最后一次使用它们之后从范围中释放变量(这使得 lldb-ing 有时是 PitA,但无论如何)

以下示例在 macOS 10.11.6 上的 Xcode 8.2.1 上的 Swift 3.0.2 中始终有效:

class Test
{
func runTest() {
var object:NSObject? = NSObject()
myMethod(arg0: object)

DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + 1.0,
qos: .userInteractive,
flags: DispatchWorkItemFlags.enforceQoS
){
object = nil
}
}

func myMethod(arg0:AnyObject?) {
weak var arg0Weak = arg0
// `arg0` get “released” at this point.  Note: It's essential that you
// don't use `arg0` in the rest of this method; only use `arg0Weak`.

NSLog("\(arg0Weak)"); // Optional(<NSObject: 0x600000000810>)

DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + 2.0,
qos: .userInteractive,
flags: DispatchWorkItemFlags.enforceQoS
){
NSLog("\(arg0Weak)"); // nil
}
}
}

Test().runTest()

请注意,如果您在 Playground 中尝试此操作,Playground 将在 DispatchQueue 触发之前完成执行。让可执行文件无限期运行的最简单方法(我所做的)是创建一个新的 Cocoa 应用程序并将上面的所有代码粘贴到 func applicationDidFinishLaunching(_:Notification) { ... } (是的,一字不差——Swift 允许类定义嵌套在方法中)


作为对线程安全讲座的回应,您已经克服了在您的示例中使用dispatch_asyncsleep 的问题,以证明弱args 确实是真正的交易,这是一个完整的 main.m 测试源变体,它是单线程和无队列的:

#import <Foundation/Foundation.h>


@interface Test : NSObject
- (void)runTest;
- (void)myMethod:(__weak id)arg0 callback:(void (^)())callback;
@end


int main(int argc, const char * argv[]) {
@autoreleasepool {
[[Test new] runTest];
}
return 0;
}


@implementation Test

- (void)runTest {
__block NSObject *object = [NSObject new];
[self myMethod:object callback:^{
object = nil;
}];
}

- (void)myMethod:(__weak id)arg0 callback:(void (^)())callback {
NSLog(@"%@", arg0); // <NSObject: 0x100400bc0>
callback();
NSLog(@"%@", arg0); // (null)
}

@end

关于swift - 弱方法参数语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30904756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com