2014-11-08 46 views
-2

我想采取我的视图的维度,并将其分配给我的scrollView。这是我的代码:Swift optionals OptionalValue

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 
    // Override point for customization after application launch. 

    var screenRect:CGRect = self.window?.bounds 

    var bigRect = screenRect 
    bigRect.size.width *= 2.0 
    bigRect.size.height *= 2.0 

    var scrollView:UIScrollView = UIScrollView(frame: screenRect) 
    self.window?.addSubview(scrollView) 

    var hypnoView:View = View(frame: bigRect) 
    scrollView.addSubview(hypnoView) 

    scrollView.contentSize = bigRect.size 

    self.window?.backgroundColor = UIColor.whiteColor() 


    return true 
} 

当我写这篇文章的Xcode var screenRect:CGRect = self.window?.bounds的Xcode给我一个错误OptionalValue .... I M接受到很多theese自选失去了什么?。 如何翻译旧的客观-c线

CGRect screenRect = self.window.bounds 

转换成swift?

回答

4

var screenRect = self.window!.bounds会为你工作。

请注意,您的应用程序会崩溃这一行,如果self.window是零,因为这是!运营商做什么:解开可选,崩溃,如果它是nil

在这种情况下,变量的类型为UIWindow?,这意味着它可能有UIWindow,或者可能是nil。如果你想访问UIWindow对象,你必须打开它。在这种特定情况下,我建议!出于特定原因。请继续阅读:

是的,!这里会让你的代码崩溃,如果self.windownil。那为什么要用这个?通过这样做,你断言你期望self.window已被设置,它是nil是一个错误条件,并且你的想要你的应用程序大声而明显地崩溃。您会看到崩溃,并查看代码中的其他位置以修复实际错误。也许你没有在Interface Builder中连接IBOutlet的窗口,或者其他的东西。

参照原来的职位,有说self.window?.bounds的问题是这样的:当你写的,你说“尝试展开window - 如果它是零,没什么大不了的,只是返回nil,而不是试图让bounds 。但screenRect类型为CGRect(没有问号),这意味着它不能nil。所以,你的代码不编译。

如果你真的想screenRect成为可能比零,你会需要声明screenRectCGRect?,这意味着它可以有一个CGRect,或可能是nil

最后,请阅读这篇文章,以更好地了解选配:https://mikeash.com/pyblog/friday-qa-2014-06-20-interesting-swift-features.html

+0

任何好的教程在可选?我读了一些,我得到了它们的用途,但是当它使用它们时,它从来没有出现在我的脑海里 – Marco 2014-11-08 19:22:24

+0

答案有一个很大的错误:你建议使用强制展开'!',但是你会说:_ “窗户可能是零”_。如果可选项为零,则使用强制解包会导致运行时异常。应该使用可选绑定或显式检查nil。 – Antonio 2014-11-08 20:42:09

+0

@Antonio:请阅读上面的讨论与nhgrif的答案。在这种情况下,当'self.window'为'nil'时,您特别*希望*您的代码大声崩溃。 – DPlusV 2014-11-08 20:55:22

2

在这种特定的情况下,最好的选择可能是,如DPlusV在他回答的第一个行提示:

var screenRect: CGRect = self.window!.bounds 

这将崩溃如果self.windownil,但鉴于在这种特定情况下,我们在didFinishLaunching,如果self.window在某种程度上nil,我们还有其他更大的问题。

然而,Swift的optionals还有两种方法,您应该使用的三个选项中的哪一个是依赖于情境的。


我们可以在第一线更改为更具这样的:

var screenRect: CGRect = self.window?.bounds ?? CGRectZero 

,它会工作。在selfwindow属性为nil的情况下,则screenRect将仅被创建为原点为(0,0)且大小为(0,0)的矩形。这将确保我们始终初始化screenRect,从不为零,并且始终执行以下所有代码。


否则,如果我们要让下面的代码只有当我们能够得到一个矩形出self.window?.bounds执行,那么我们可能会尝试更多的东西是这样的:

if let screenRect = self.window?.bounds { 
    var bigRect = screenRect 

    // etc., all the rest of your code 
} 

return true 
+0

虽然这个答案可以解决眼前的问题,但我不建议在这种情况下。在'nil'的情况下,新手开发人员会花费数小时的时间想知道为什么他们的矩形为零。代码应该是自以为是的:开发者应该决定在一天结束时他们是否想要某些东西有时是“无”的。你的方法只是吞并问题,而不是强迫开发人员编写正确的代码。 – DPlusV 2014-11-08 18:07:32

+0

我的答案提供了两种方法。确实,'screenRect'可能应该是一个'无'CGREct'。相反,我们应该采取“如果让”的方法,而不是在后面的每一步都检查它是否为“无”。 – nhgrif 2014-11-08 18:12:20

+0

这是一个设定期望值的问题。例如,如果您正在从数据库中读取姓名,年龄和职业,并且可能未设置职业,则使用您的方法是完全合适的。那里没有职业是有效的。但在这种情况下,如果'self.window'为'nil',那么会有一个bug,他们会默默地隐藏它。 – DPlusV 2014-11-08 18:20:56

相关问题