扫描二维码,下载安卓APP
下载安卓APP箭头
客服QQ
箭头给我发消息

客服QQ:2698585038
论坛 >编程语言 >初始化返回 NIL

初始化返回 NIL

为了部落发布于 2017-08-22 09:36查看:8123回复:1

        在 Objective-C 中,init 方法除了返回 self 以外,其实和一个普通的实例方法并没有太大区别。如果你喜欢的话,甚至可以多次进行调用,这都没有限制。一般来说,我们还会在初始化失败 (比如输入不满足要求无法正确初始化) 的时候返回 nil 来通知调用者这次初始化没有正确完成。

        但是,在 Swift 中默认情况下初始化方法是不能写 return 语句来返回值的,也就是说我们没有机会初始化一个 Optional 的值。一个很典型的例子就是初始化一个 url。在 Objective-C 中,如果我们使用一个错误的字符串来初始化一个 NSURL 对象时,返回会是 nil 代表初始化失败。所以下面这种 “防止度娘吞链接” 式的字符串 (注意两个 t 之间的空格和中文的句号) 的话,也是可以正常编译和运行的,只是结果是个 nil

1503365538842539.jpg

        但是在 Swift 中情况就不那么乐观了,-initWithString: 在 Swift 中对应的是一个 convenience init 方法:init(string URLString: String!)。上面的 Objective-C 代码在 Swift 中等效为:

1503365565983794.jpg

     init 方法在 Swift 1.1 中发生了很大的变化,为了将来龙去脉讲述清楚,我们先来看看在 Swift 1.0 下的表现。

        Swift 1.0 及之前

        如果在 Swift 1.0 的环境下尝试运行上面代码的话,我们会得到一个 EXC_BAD_INSTRUCTION,这说明触发了 Swift 内部的断言,这个初始化方法不接受这样的输入。一个常见的解决方法是使用工厂模式,也就是写一个类方法来生成和返回实例,或者在失败的时候返回 nil。Swift 的 NSURL 就做了这样的处理:

1503365648857179.jpg

        使用的时候:

1503365671362190.jpg

        不过虽然可以用这种方式来和原来一样返回 nil,但是这也算是一种折衷。在可能的情况下,我们还是应该倾向于尽量减少出现 Optional 的可能性,这样更有助于代码的简化。

        如果你确实想使用初始化方法而不愿意用工厂函数的话,也可以考虑用一个 Optional 量来存储结果。

        这样你就可以处理初始化失败了,不过相应的代价是代码复杂度的增加。

    let url: NSURL? = NSURL(string: "http://")

        结果为 nil

        Swift 1.1 及之后

        虽然在默认情况下不能在 init 中返回 nil,但是通过上面的例子我们可以看到 Apple 自家的 API 还是有这个能力的。

        好消息是在 Swift 1.1 中 Apple 已经为我们加上了初始化方法中返回 nil 的能力。我们可以在 init 声明时在其后加上一个 ? 或者 ! 来表示初始化失败时可能返回 nil。比如为 Int 添加一个接收 String 对其解析并初始化的时候,就可能遇到初始化失败的情况:

1503365735682768.jpg

    number 和 notNumber 都将是 Int? 类型,通过 Optional Binding,我们就能知道初始化是否成功,并安全地使用它们了。我们在这类初始化方法中还可以对 self 进行赋值,也算是 init 方法里的特权之一。

        同时像上面例子中的 NSURL.URLWithString 这样的工厂方法,在 Swift 1.1 中已经不再需要。为了简化 API 和安全,Apple 已经被标记为不可用了并无法编译。而对应地,可能返回 nil 的 init 方法都加上了 ? 标记:

1503365764308758.jpg

        在新版本的 Swift 中,对于可能初始化失败的情况,我们应该始终使用可返回 nil 的初始化方法,而不是类型工厂方法。

收藏(0)0
查看评分情况

全部评分

此主贴暂时没有点赞评分

总计:0

回复分享

版主推荐

    共有1条评论

    • Mr ken
    • YUI
    • cappuccino
    • mr jack
    • IT宅男
    • Mright
    • 选择版块:

    • 标题:

    • 内容

    • 验证码:

    • 标题:

    • 内容

    • 选择版块:

    移动帖子x

    移动到: