我不再看到Xcode抱怨某些事情需要选项("?")。现在它总是被迫解开(爆炸"!")。当我们现在强行打开包装时,有没有理由再使用选项?
答案 0 :(得分:1)
当你写下你不再看到Xcode抱怨"某些事情需要选项时,我真的不知道你的意思。现在它总是被强行打开" 。这两句话相互矛盾:
或许你的想法是,当你实际强制解包选项时,Xcode似乎不太经常抱怨,或者,作为Xcode的坏习惯,提示你强行打开包装以避免编译时错误。这通常是因为Xcode在编译时无法知道您刚编写的代码会在运行时破坏您的应用程序。
Xcode似乎有时只有一个单一的目的,它的"智能提示":即免除编译时错误。如果您尝试将select t1.*,t2.idx,t2.belongTo,t2.datetime1
from table1 t1
inner join
(
select t11.idx,t11.belongTo,t11.datetime1,count(*) as row_number from
table2 t11
inner join table2 t12
on t11.belongTo=t12.belongTo
and t11.datetime1 <= t12.datetime1
group by t11.belongTo,t11.datetime1
) t2 /*this table will create row_number based on max datetime value for each belongTo*/
on t1.idx=t2.belongTo
where t2.row_number=1
类型的值(可选String?
)分配给String
类型,Xcode将提示您编译错误并询问您是否要添加强制解包运算符String
。你说,智能Xcode?嗯,Xcode很适合很多东西,但是决定你如何解开你的选择权,不管怎样,其中之一就是其中之一。因此,即使Xcode提示您进行各种操作:如果您可以使用可选链接,请执行。
当然可能有例外。对于MVC设计pardigm的控制器部分,通常使用!
运算符来执行强制转换&#34; (投射),Xcode有时会告诉您明确使用as!
代替as!
,例如&#34;您的意思是as
......?&#34; 。在这些情况下,Xcode有时实际上可以知道它在做什么,并推断你试图投射,例如,一个自定义的as!
类实例,以键入UIViewController
,即,它,...父母班。我说这可能是我使用&#34;强迫&#34;的少数几次之一。标记UIViewController
没有复飞;强制转换为我知道的类型,100%确定是可投射的。
但是,让我们留下类型转换/转换的主题,并继续进行可选类型,包装和可选链接。
通常,您应该避免强行展开,除非您明确知道您打开的实体将是非零的。对于一般类属性,变量等,假设您按照您的方式陈述此问题,我将提供以下建议:
如果你可以使用条件展开(
!
,if-let
,则为零 合并运算符guard-let
),然后不使用强制解包(??
)。
下面是强制展开危险的一个例子。您可以将第一个!
子句(if
)视为您使用命令式编程技术编写的某个程序中较小或较大的部分:我们并不真正详细了解如何&#39;名称&#39;结果将持续到运行时,我们的编译器无法真正帮助我们。
if arc4random...
我建议你阅读可选链接,这是Swift中的一个关键主题。
答案 1 :(得分:0)
protocol AnyObject { ... }
所有类隐式符合的协议。
当用作具体类型时,所有已知的@objc方法和属性都可用,分别作为AnyObject的每个实例上的隐式解包 - 可选方法和属性。例如:
class C {
@objc func getCValue() -> Int { return 42 }
}
// If x has a method @objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: AnyObject) -> Int? {
if let f: ()->Int = x.getCValue { // <===
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: AnyObject) -> Int? {
return x.getCValue?() // <===
}
// An implementation that assumes the required method is present
func getCValue3(x: AnyObject) -> Int { // <===
return x.getCValue() // x.getCValue is implicitly unwrapped. // <===
}