ios – 在易错初始化程序swift 1.2中分配let变量

前端之家收集整理的这篇文章主要介绍了ios – 在易错初始化程序swift 1.2中分配let变量前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个带有易错初始化程序的结构,不是实例方法,而是初始化程序.更新到1.2后,当我尝试在初始化程序中分配一个let属性时,我收到以下错误无法在self中分配给’aspectRatio’.我的代码如下:
import Foundation

public struct MediaItem
{
public let url: NSURL!
public let aspectRatio: Double

public var description: String { return (url.absoluteString ?? "no url") + " (aspect ratio = \(aspectRatio))" }

// MARK: - Private Implementation

init?(data: NSDictionary?) {
    var valid = false
    if let urlString = data?.valueForKeyPath(TwitterKey.MediaURL) as? NSString {
        if let url = NSURL(string: urlString as String) {
            self.url = url
            let h = data?.valueForKeyPath(TwitterKey.Height) as? NSNumber
            let w = data?.valueForKeyPath(TwitterKey.Width) as? NSNumber
            if h != nil && w != nil && h?.doubleValue != 0 {
                aspectRatio = w!.doubleValue / h!.doubleValue
                valid = true
            }
        }
    }
    if !valid {
        return nil
    }
}

struct TwitterKey {
    static let MediaURL = "media_url_https"
    static let Width = "sizes.small.w"
    static let Height = "sizes.small.h"
}
}

我的问题是我该怎么做才能解决这个问题?

解决方法

Swift 1.2已经关闭了与let属性有关的漏洞:

The new rule is that a let constant must be initialized before use (like a var),and that it may only be initialized,not reassigned or mutated after initialization.

该规则正是您试图违反的规则. aspectRatio是一个let属性,你已经在它的声明中给它一个值:

public let aspectRatio: Double = 0

因此,在我们到达初始化程序之前,aspectRatio的初始值为0.这是它可以拥有的唯一值.新规则意味着您永远不能再分配给aspectRatio,即使在初始化程序中也是如此.

解决方案是(这始终是正确的方法):在声明中没有给它赋值:

public let aspectRatio: Double

现在,在初始化程序中,将其指定为0或指定它!.doubleValue / h!.doubleValue.换句话说,一次处理初始化程序中的所有可能性.无论如何,这将是唯一一次为aspectRatio分配值的时间.

如果你考虑一下,你会发现这是一种更明智和一致的方法;以前,你对let的含义有点搪塞,新规则已经阻止了你这样做.

在重写代码时,如果您想要挽救并返回nil,则无法初始化所有属性.我知道这似乎违反直觉,但你做不到.即使您打算纾困,也必须初始化所有属性.我非常清楚地讨论这个问题in my book

A failable class initializer cannot say return nil until after it has completed all of its own initialization duties. Thus,for example,a failable subclass designated initializer must see to it that all the subclass’s properties are initialized and must call super.init(...) before it can say return nil. (There is a certain delicIoUs irony here: before it can tear the instance down,the initializer must finish building the instance up.)

编辑:请注意,从Swift 2.2开始,此要求将被取消.在初始化属性之前返回nil是合法的.这将使类初始化器与struct初始化器相提并论,这已经是合法的.

猜你在找的iOS相关文章