ios - 如何在 Swift 中正确重构对象初始化的第一阶段?

标签 ios swift

所以我在 Swift 中了解到我们应该使用两阶段初始化:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html

规则之一是:“在第一阶段初始化完成之前,初始化程序不能调用任何实例方法、读取任何实例属性的值或将自身作为值引用。”

这可以防止在实例方法中放置代码块,所以我猜应该使用类方法?你怎么看?任何替代解决方案?

为了说明我的意思,这里有 3 个代码示例:

未重构的代码:

@objc class MYChatBarButton: UIBarButtonItem {

    let badgeLabel: UILabel


    init(target: AnyObject, selector: Selector) {

        let button = UIButton.buttonWithType(.Custom) as UIButton
        button.frame = CGRectMake(0, 0, 35, 44)
        button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
        button.tintColor = UIColor.whiteColor()
        button.setImage(UIImage(named: "chat_icon")?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 7, bottom: 5, right: 0)

        badgeLabel = UILabel(frame: CGRectMake(0, 0, 15, 15))
        badgeLabel.backgroundColor = UIColor.clearColor()
        badgeLabel.textColor = UIColor.whiteColor()
        badgeLabel.textAlignment = .Center
        badgeLabel.text = "0"
        badgeLabel.userInteractionEnabled = false

        button.addSubview(badgeLabel)


        super.init(customView: button)


    }


}

我期望进行重构但它不起作用的方式:

@objc class MYChatBarButton: UIBarButtonItem {

    let badgeLabel: UILabel


    init(target: AnyObject, selector: Selector) {

        let button = createButton(target, selector: selector)
        createBadgeLabel()
        button.addSubview(badgeLabel)

        super.init(customView: button)


    }

    func createButton(target: AnyObject, selector: Selector) -> UIButton {
        let button = UIButton.buttonWithType(.Custom) as UIButton
        button.frame = CGRectMake(0, 0, 35, 44)
        button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
        button.tintColor = UIColor.whiteColor()
        button.setImage(UIImage(named: "chat_icon")?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 7, bottom: 5, right: 0)
        return button
    }

    func createBadgeLabel() {
        badgeLabel = UILabel(frame: CGRectMake(0, 0, 15, 15))
        badgeLabel.backgroundColor = UIColor.clearColor()
        badgeLabel.textColor = UIColor.whiteColor()
        badgeLabel.textAlignment = .Center
        badgeLabel.text = "0"
        badgeLabel.userInteractionEnabled = false
    }

}

它可能应该完成的方式(但我不太喜欢它):

@objc class MYChatBarButton: UIBarButtonItem {

    let badgeLabel: UILabel


    init(target: AnyObject, selector: Selector) {

        let button = MYChatBarButton.createButton(target, selector: selector)
        badgeLabel = MYChatBarButton.createBadgeLabel()
        button.addSubview(badgeLabel)

        super.init(customView: button)


    }

    class func createButton(target: AnyObject, selector: Selector) -> UIButton {
        let button = UIButton.buttonWithType(.Custom) as UIButton
        button.frame = CGRectMake(0, 0, 35, 44)
        button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
        button.tintColor = UIColor.whiteColor()
        button.setImage(UIImage(named: "chat_icon")?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 7, bottom: 5, right: 0)
        return button
    }

    class func createBadgeLabel() -> UILabel {
        let bl = UILabel(frame: CGRectMake(0, 0, 15, 15))
        bl.backgroundColor = UIColor.clearColor()
        bl.textColor = UIColor.whiteColor()
        bl.textAlignment = .Center
        bl.text = "0"
        bl.userInteractionEnabled = false
    }

}

最佳答案

至少,您可以隔离 badgeLabel 创建:

@objc class MYChatBarButton: UIBarButtonItem {

    let badgeLabel: UILabel = {
        let bl = UILabel(frame: CGRectMake(0, 0, 15, 15))
        bl.backgroundColor = UIColor.clearColor()
        bl.textColor = UIColor.whiteColor()
        bl.textAlignment = .Center
        bl.text = "0"
        bl.userInteractionEnabled = false
        return bl
    }()

    let button: UIButton = {
        let button = UIButton.buttonWithType(.Custom) as UIButton
        button.frame = CGRectMake(0, 0, 35, 44)
        button.tintColor = UIColor.whiteColor()
        button.setImage(UIImage(named: "chat_icon")?.imageWithRenderingMode(.AlwaysTemplate), forState: .Normal)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 7, bottom: 5, right: 0)
        return button
    }()

    init(target: AnyObject, selector: Selector) {
        button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
        button.addSubview(badgeLabel)
        super.init(customView: button)
    }

没有属性(property)我不知道该怎么做。

关于ios - 如何在 Swift 中正确重构对象初始化的第一阶段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27488157/

相关文章:

iphone - 获取苹果 "External Accessory framework"蓝牙设备的MAC地址

ios - 更新到 Xcode 10.2 后出现 PDFKit 问题。有什么办法解决吗?

ios - Swift 冗余一致性

ios - 覆盖 AppDelegate 上的初始化 - 防止代码多次执行

ios - UISplitViewController 的主视图中未调用 viewWillAppear

iphone - 用varargs编写replaceTokensWithStrings:方法

ios - UIButton颜色在iphone 8 plus和iphone X中有渐变(iOS版本独立问题)

swift - 来自 https 请求的奇怪 MLFeatureValue 响应

swift - 为什么我的 Objective-C block 在传递给 Swift 函数时没有显示?

objective-c - 在 nsstring 中查找和替换所有内容