不推荐使用 Objective-C 选择器的字符串文字,改用 '#selector'

Posted

技术标签:

【中文标题】不推荐使用 Objective-C 选择器的字符串文字,改用 \'#selector\'【英文标题】:Use of string literal for Objective-C selectors is deprecated, use '#selector' instead不推荐使用 Objective-C 选择器的字符串文字,改用 '#selector' 【发布时间】:2016-03-23 04:48:11 【问题描述】:

我有以下代码:

func setupShortcutItems(launchOptions: [NSObject: AnyObject]?) -> Bool 
    var shouldPerformAdditionalDelegateHandling: Bool = false

    if (UIApplicationShortcutItem.respondsToSelector("new")) 
        self.configDynamicShortcutItems()

        // If a shortcut was launched, display its information and take the appropriate action
        if let shortcutItem: UIApplicationShortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem 
            // When the app launched at the first time, this block can not called.
            self.handleShortCutItem(shortcutItem)

            // This will block "performActionForShortcutItem:completionHandler" from being called.
            shouldPerformAdditionalDelegateHandling = false
         else 
            // normal app launch process without quick action
            self.launchWithoutQuickAction()
        
     else 
        // Less than ios9 or later
        self.launchWithoutQuickAction()
    

    return shouldPerformAdditionalDelegateHandling

我在UIApplicationShortcutItem.respondsToSelector("new") 上收到以下“警告”,上面写着:

Objective-c 选择器不推荐使用字符串文字,请改用“#selector”

警告自动将代码替换为:

UIApplicationShortcutItem.respondsToSelector(#selector(FBSDKAccessToken.new))

但是这不能编译,因为new() 不可用。 在这种情况下我应该使用什么?

【问题讨论】:

检查这个...也许你有什么东西***.com/questions/36147831/syntax-selector-swift-2-2 你为什么要测试选择器new?我在这里看不到任何发送new 消息的代码。 【参考方案1】:

Xcode 7.3 使用 swift for iOS9.3/watchOS2.2/...

如果你之前使用过这行代码:

NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateResult:", name: "updateResult", object: nil)

你现在应该使用这行代码:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(InterfaceController.updateResult(_:)), name: "updateResult", object: nil)

至少这是在我更改代码中的几个字符后 Xcode 提供给我的。当您遇到此错误时,似乎它并不总是提供正确的解决方案。

【讨论】:

这对我有用,比选择的答案更好。 button.addTarget(self, action: #selector(ViewController.onClickStart), for: .touchUpInside) 我用这个。谢谢 ! @Florian Uhlemann【参考方案2】:

创建一个协议,其存在的唯一原因是允许您构造适当的选择器。在这种情况下:

@objc protocol NewMenuItemHandling 
  func new()
 

您正在采用非正式协议(响应新选择器的对象)并将其变成正式协议。

然后在你想使用选择器的地方添加表达式:

#selector(NewMenuItemHandling.new)

【讨论】:

鬼鬼祟祟。 我不知道我会称之为偷偷摸摸。基本上,Objective-C 很大程度上依赖于非正式协议(如果您愿意,也可以使用 Duck Typing)。 Swift 希望对协议更正式一点。所以你采用了一个非正式的协议并告诉 Swift 它存在 :-)【参考方案3】:

在这种特殊的respondsToSelector 情况下,您没有与函数引用关联的现有方法,请编写以下代码:

UIApplicationShortcutItem.respondsToSelector(Selector("new"))

你仍然会收到一个警告(你不应该,而且我已经针对它提交了一个错误),但它会是一个不同的警告,你可以忽略它。

【讨论】:

真正的笑话是,您应该可以通过说#selector(NSObject.new) 来摆脱这种情况,因为这确实是您的意思的new。但是当你这么说时,你得到的是错误而不是警告! @gotnull 这是 Apple 对我的错误报告的回复:“工程部门已确定您的错误报告 (24815319) 与另一个问题 (24791200) 重复,将被关闭。”请随意堆积:重复越多越好。【参考方案4】:

总之,每个“选择器:函数或对象”现在都是“选择器:#selector(class.funtion(_:))”。

【讨论】:

以上是关于不推荐使用 Objective-C 选择器的字符串文字,改用 '#selector'的主要内容,如果未能解决你的问题,请参考以下文章

Swift - 带有Objective-C选择器'*'的方法'*()'与具有相同Objective-C选择器的超类'UIView'中的'*'的getter冲突

快速更改选择器的字体及其大小

使用 jQuery 星形选择器的 Rails 表单

什么取代了不推荐使用的属性 this.selector

选择器的基本规则及使用

选择器的基本规则及使用