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

Mik*_*hke 13 objective-c swift

我见过这样的代码,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!)
Run Code Online (Sandbox Code Playgroud)

原始代码是:

- (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;
Run Code Online (Sandbox Code Playgroud)

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

And*_*rew 18

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

要直接回答您的问题,它是一个初始化程序,它返回一个隐式解包的可选项.

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

隐式解包的选项表示您可以确信您当前使用的值不是零,而不必检查它,但它在其生命周期中的某个时刻可能是零.这与非可选类型形成鲜明对比,后者永远不会是零.由于您从初始化程序获取值时从一生中开始使用值,因此用例不多init!.

它可能主要用于帮助Objective-C框架转换,以避免必须手动检查每个自动转换的初始化程序."这可能是零但可能不是"是Objective-C默认工作的方式.在您的情况下,Xcode无法知道这些方法是否在100%的时间内返回初始化值.通过每个单独的框架并确定初始化是否应该返回a Type或者Type?,Type!同时是一个合理的默认值是相当努力的.作为证明,Xcode的足够聪明的转换包含初始化(NSError **)init?.

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

资料来源:


nic*_*ael 14

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

来自Apple Developer:

初学者!可用的初始化程序

您通常会定义一个可用的初始值设定项,通过在init关键字(init?)后面放置一个问号来创建相应类型的可选实例 .或者,您可以定义一个可用的初始值设定项,用于创建相应类型的隐式解包的可选实例.通过在init关键字(init!)后面放置一个感叹号而不是问号来做到这一点 .

您可以从委托init?init!,反之亦然,你可以覆盖init?init!反之亦然.您也可以委托 init自己init!,尽管这样做会在init!初始化程序导致初始化失败时触发断言 .

(强调我的)