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

详细说明,这是一个按预期工作的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无法变为零?
谢谢!

从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中一致地工作:

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,flags: dispatchWorkItemFlags.enforceQoS
        ){
            NSLog("\(arg0Weak)"); // nil
        }
    }
}

test().runtest()

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

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

#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 – 弱方法参数语义的更多相关文章

  1. ios – 如何使用string中的参数创建Selector

    我正在使用Swift3.1和Xcode8.3.3编写程序.我想创建一个类,负责在键盘出现和消失时移动整个视图.但是我在使用字符串参数创建自定义选择器时遇到了困难.要显示或隐藏键盘我们需要功能:我正在尝试创建一个这样的选择器:它正在编译,但是当键盘出现时,它会崩溃.因为它是独立的类我不能使用这种结构:因为它将Swift函数转换为Objective-C函数.所以问题是:如何用参数字符串创建一个Selector表单?

  2. ios – 为什么,将nil作为参数从Objc C发送到swift类初始化器,用新对象替换nil参数

    除非属性本身被声明为nonnull:

  3. ios – 如何为NSNotification编写单元测试

    我在swift工作,我想刷新一个页面,所以我使用通知发送它,我在一个ViewController中发布通知并在另一个中添加观察者,它工作正常.我想要做的是在swift中添加单元测试.我查了很多网站但是没能做到.我是新手,不知道从哪里开始.基本上工作是,当我点击按钮通知被发布时,并且当加载下一个视图控制器时,添加通知观察者.我该怎么做单元测试提前致谢编辑:码并添加观察者解决方法一般的解决方案是:使用

  4. iOS 6 javascript与object.defineProperty的间歇性问题

    当访问使用较新的Object.defineProperty语法定义属性的对象的属性时,有没有其他人注意到新iOS6javascript引擎中的间歇性错误/问题?https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty我正在看到javascript失败的情况,说

  5. ios – NSNotificationCenter多次呼叫

    我在我的应用程序中实现了NSNotificationCenter.我在完成图像解码时发送通知.第一次图像解码将完成8次.所以通知假设发送8次.但它调用64次(8*8).这是我的代码我是如何实现的–>//初始化//调用方法//解除分配//发布通知有人可以建议我做错了.提前致谢.//调用方法是这样的(调用8次)解决方法解:我重新检查了我的代码,initWithFrame:(CGRect)框架调用了8次

  6. ios – 使用NSMutableAttributedStrings快速更改文本颜色

    我有一个UITableView,我想在同一行中使用不同的颜色显示每行的文本.我试过这个代码,尝试从Obj-C翻译,但我不能让它工作这一切的输出是其中数字34对应于object.valueForKey!.description)被替换为{.如果我留下关于NSAttributedString的这段代码,行文本会正确显示.解决方法我认为问题可能在于分配给cell.textLabel?.attributedText.也许是这样的:不确定你是否希望字符串的第二部分是红色或其他颜色,所以我把它变黑了.

  7. Xcode / iOS:如何隐藏Navigation-和ToolBar向下滚动?

    我想在iPhone上隐藏两个滚动条.当我向上滚动时,他们应该再次出现..我该如何处理?

  8. ios – 将阵列存储在Realm对象中

    我是Swift的新星.有没有办法在RealmObject中存储字符串数组?我有一个JSON对象像:如何将消息数组存储在权限密钥中?

  9. xcode – 使用performSelector执行的方法中的objc_retain中的崩溃

    我有这个奇怪的崩溃与ARC自动插入objc_retains在我的代码.我有以下两个类:在某些时候,我实例化一个MenuItem:然后在其他地方,我在菜单项上调用performAction:在执行某些方法我遇到崩溃:为什么会这样?

  10. ios – “点击恢复”暂停文本SpriteKit

    我知道当应用程序进入非活动状态时,SpriteKit已处理暂停游戏,但我正在尝试做的是在应用程序重新进入活动状态时添加SKLabelNode“点击以恢复”.现在它正在调用我的函数并暂停游戏,但文本没有显示.AppDelegate.swiftGameScene.swift编辑:下面是我的终端输出的屏幕截图,其中包含我对上述代码的最新修改:解决方法所以我在这里“破解”了我的解决方案.感谢ABakerS

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部