首页 文章

感叹号对于快速初始化程序意味着什么?

提问于
浏览
13

我见过这样的代码,XCode是从objective-c初始化器创建的:

init!(logMsg: String!, level logLevel: DDLogLevel, flag logFlag: DDLogFlag, context logContext: Int32, file: UnsafePointer<Int8>, function: UnsafePointer<Int8>, line: Int32, tag: AnyObject!, options optionsMask: DDLogMessageOptions)
init!(logMsg: String!, level logLevel: DDLogLevel, flag logFlag: DDLogFlag, context logContext: Int32, file: UnsafePointer<Int8>, function: UnsafePointer<Int8>, line: Int32, tag: AnyObject!, options optionsMask: DDLogMessageOptions, timestamp aTimestamp: NSDate!)

原始代码是:

- (instancetype)initWithLogMsg:(NSString *)logMsg
                         level:(DDLogLevel)logLevel
                          flag:(DDLogFlag)logFlag
                       context:(int)logContext
                          file:(const char *)file
                      function:(const char *)function
                          line:(int)line
                           tag:(id)tag
                       options:(DDLogMessageOptions)optionsMask;
- (instancetype)initWithLogMsg:(NSString *)logMsg
                         level:(DDLogLevel)logLevel
                          flag:(DDLogFlag)logFlag
                       context:(int)logContext
                          file:(const char *)file
                      function:(const char *)function
                          line:(int)line
                           tag:(id)tag
                       options:(DDLogMessageOptions)optionsMask
                     timestamp:(NSDate *)aTimestamp;

init 关键字后感叹号的含义是什么?

3 回答

  • 1

    它是可用的初始化程序,在Swift 1.1中引入(带有Xcode 6.1)

    来自Apple Developer

    初学者! Failable Initializer您通常定义一个可用的初始化程序,通过在init关键字(init?)后面放置一个问号来创建相应类型的可选实例 . 或者,您可以定义一个可用的初始值设定项,用于创建相应类型的隐式解包的可选实例 . 通过在init关键字(init!)之后放置一个感叹号而不是问号来做到这一点 . 你可以从init委派?初始化!反之亦然,你可以覆盖init吗?用init!反之亦然 . 你也可以从init委托给init !,虽然这样做会触发init的断言!初始化程序导致初始化失败 .

    (强调我的)

  • 17

    目前接受的答案给出了什么,但不是原因 . 我认为在这种情况下,理解为什么特别重要 .

    要直接回答您的问题,它是一个返回implicitly-unwrapped optional的初始值设定项 .

    使用 init? 表示初始化可能失败是处理错误的有效方法 . 它返回"optional"(例如 Type? ),暗示值已初始化,或者没有任何内容可以初始化,其内容为 nil . 但什么时候会返回一个隐式解包的可选项 init! 会有用吗?

    隐式解包的选项表明,当您从初始化程序获取值时,您可以确信从一生中开始使用值的值, init! 的用例不多 .

    它可能主要用于帮助Objective-C框架转换,以避免必须手动检查每个自动转换的初始化程序 . "This thing might be nil but probably isn't"是Objective-C默认工作的方式 . 在你的情况下,有很多努力要经历每一个框架,并弄清楚初始化是否应该返回 TypeType? ,所以 Type! 在此期间是一个合理的默认值 . 作为证明,Xcode非常智能,可以将包含 (NSError **) 的初始化程序转换为 init? .

    另一个用例是委托给一个可用的初始化程序,你知道它永远不会导致失败 . 但除此之外,在可能的情况下,应该尽可能避免在自己的Swift代码中编写 init! (即使这种情况仍然相当不确定) .

    资料来源:

  • 13

    这些被称为'隐含地解开的选项'[1] . logMsg的obj-c类型(例如)是NSString *,可以是nil . 它可以用作可选的 - String ?,在这种情况下,你可以明确地解包它来获取值 . 串!会直接给你这个值,所以这假设logMsg不会是nil .

    这些类型的期权被定义为隐式解包的期权 . 您通过在要使其成为可选的类型之后放置感叹号(String!)而不是问号(String?)来编写隐式展开的可选项 . 当在首次定义可选项之后立即确认可选的值存在时,隐式展开的选项很有用,并且可以假定在此后的每个点都存在 .

    1. https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html

相关问题