swift – 弱方法参数语义

前端之家收集整理的这篇文章主要介绍了swift – 弱方法参数语义前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有办法指定特定方法参数具有弱语义?

详细说明,这是一个按预期工作的Objective-C示例代码

  1. - (void)runTest {
  2. __block NSObject *object = [NSObject new];
  3. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
  4. [self myMethod:object];
  5. });
  6. // to make sure it happens after `myMethod:` call
  7. dispatch_async(dispatch_get_main_queue(),^{
  8. object = nil;
  9. });
  10. }
  11. - (void)myMethod:(__weak id)arg0 {
  12. NSLog(@"%@",arg0); // <NSObject: 0x7fb0bdb1eaa0>
  13. sleep(1);
  14. NSLog(@"%@",arg0); // nil
  15. }

这是Swift版本,但没有

  1. public func runTest() {
  2. var object: NSObject? = NSObject()
  3. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)) {
  4. self.myMethod(object)
  5. }
  6. dispatch_async(dispatch_get_main_queue()) {
  7. object = nil
  8. }
  9. }
  10. private func myMethod(arg0: AnyObject?) {
  11. println("\(arg0)") //Optional(<NSObject: 0x7fc778f26cf0>)
  12. sleep(1)
  13. println("\(arg0)") //Optional(<NSObject: 0x7fc778f26cf0>)
  14. }

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

从Apple Dev.Forums更新用户指出睡眠不是一个好用的函数,连续调度可能会导致竞争条件.虽然这些可能是合理的问题,但这只是一个示例代码,问题的焦点在于传递弱论点.

Swift没有“弱args”……但这可能只是因为Swift(3.0)args是不可变的(相当于let)而Swift中的弱东西需要同时是var和Optional.

也就是说,确实有一种非常简单的方法可以实现相当于弱的args-使用弱的var local(释放arg-var来释放).这是有效的,因为Swift在当前作用域结束之前不会挂起变量(就像C一样严格);但是它会在最后一次使用它之后从范围中释放变量(这有时会使PitA成为PitA,但无论如何).

以下示例在macOS 10.11.6上的Xcode 8.2.1上的Swift 3.0.2中一致地工作:

  1. class Test
  2. {
  3. func runTest() {
  4. var object:NSObject? = NSObject()
  5. myMethod(arg0: object)
  6.  
  7. DispatchQueue.main.asyncAfter(
  8. deadline: DispatchTime.now() + 1.0,qos: .userInteractive,flags: DispatchWorkItemFlags.enforceQoS
  9. ){
  10. object = nil
  11. }
  12. }
  13.  
  14. func myMethod(arg0:AnyObject?) {
  15. weak var arg0Weak = arg0
  16. // `arg0` get “released” at this point. Note: It's essential that you
  17. // don't use `arg0` in the rest of this method; only use `arg0Weak`.
  18.  
  19. NSLog("\(arg0Weak)"); // Optional(<NSObject: 0x600000000810>)
  20.  
  21. DispatchQueue.main.asyncAfter(
  22. deadline: DispatchTime.now() + 2.0,flags: DispatchWorkItemFlags.enforceQoS
  23. ){
  24. NSLog("\(arg0Weak)"); // nil
  25. }
  26. }
  27. }
  28.  
  29. Test().runTest()

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

为了响应线程安全讲座,你已经使用dispatch_async&在你的例子中睡觉,以证明弱args确实是真正的交易这里是你的测试的完整的main.m-source变体,它是单线程和无队列的:

  1. #import <Foundation/Foundation.h>
  2.  
  3.  
  4. @interface Test : NSObject
  5. - (void)runTest;
  6. - (void)myMethod:(__weak id)arg0 callback:(void (^)())callback;
  7. @end
  8.  
  9.  
  10. int main(int argc,const char * argv[]) {
  11. @autoreleasepool {
  12. [[Test new] runTest];
  13. }
  14. return 0;
  15. }
  16.  
  17.  
  18. @implementation Test
  19.  
  20. - (void)runTest {
  21. __block NSObject *object = [NSObject new];
  22. [self myMethod:object callback:^{
  23. object = nil;
  24. }];
  25. }
  26.  
  27. - (void)myMethod:(__weak id)arg0 callback:(void (^)())callback {
  28. NSLog(@"%@",arg0); // <NSObject: 0x100400bc0>
  29. callback();
  30. NSLog(@"%@",arg0); // (null)
  31. }
  32.  
  33. @end

猜你在找的Swift相关文章