【问题标题】:How to override and use alloc in Swift?如何在 Swift 中覆盖和使用 alloc?
【发布时间】:2015-08-31 10:31:26
【问题描述】:

如何覆盖对象创建(alloc)并添加自定义逻辑?原因是我总是为每个模块(屏幕)使用 3 个类来构建我的通用应用程序,例如

1. LoginViewController  // this inherits from BaseViewController and holds common code for both ipad and iphone 
2. LoginViewController_iphone // custom logic for iphone only
3. LoginViewController_ipad // custom logic for ipad only

其中很酷的部分是我在代码周围使用不带后缀的控制器,因为它们都从 BaseViewController 扩展并且它覆盖了 alloc 方法,该方法执行智能逻辑并在调用 VC alloc/init 时自动选择正确的类。

现在,随着我们都开始慢慢过渡到 Swift,我也设法在 Swift 1.2 中重写并实现了 alloc 方法。这是实现:

class BaseViewController: UIViewController {

  override class func alloc() -> BaseViewController {

    var viewControllerClassName : String = NSStringFromClass(self)

    if ((viewControllerClassName.lowercaseString.rangeOfString("ipad") == nil) && (viewControllerClassName.lowercaseString.rangeOfString("iphone") == nil)) {

        switch (UIDevice.currentDevice().userInterfaceIdiom) {

        case .Pad:

            viewControllerClassName += "_ipad";

        case .Phone:

            viewControllerClassName += "_iphone";

        default:

            viewControllerClassName += "";
        }

        let viewControllerClass : AnyClass = NSClassFromString(viewControllerClassName)

        return viewControllerClass.alloc() as! BaseViewController

    } else {

        return super.alloc() as! BaseViewController
    }
}

今天,我下载了带有 Swift 2 的 Xcode 7 beta 6 并尝试编译项目,但收到令人讨厌的意外消息“alloc() 在 Swift 中不可用:请改用对象初始化器”。好吧,我不介意其他开发人员更喜欢使用不同的方法,但是拥有更多的灵活性总比拥有更少的灵活性好。有人知道如何覆盖类对象的创建并添加自定义逻辑吗?

【问题讨论】:

  • 最好将这种Objective-C hacks 保留在Objective-C 中。纯 swift 类型无论如何都不会使用 alloc。
  • @NikolaiRuhe 是的,但无论如何仍然需要一些 hack,例如 Reflection thingies,带有方法调配的 SideMenu 解决方案,依赖注入框架,如 Typhoon。这就是我在使用 Swift 的初始步骤中正在寻找的东西,因为 Objc 具有强大的功能,而不管其奇特的语法如何,因此将大型应用程序解决方案从 Objc 过渡到 Swift 并不像它应该的那样顺利,至少现在是这样:)

标签: ios swift alloc


【解决方案1】:

Alloc being callable was an oversight,根据 Swift 开发者 Chris Lattner 的说法。

您将不得不迁移到对象初始化器。

【讨论】:

  • 感谢您的参考。该死,讨厌回退到不太优雅的解决方案,因为在使用情节提要时无法拥有类似的功能。因为视图控制器名称在故事板中是硬编码的,并且无法自动选择相关的 ipad 或 iphone 子类。
  • 您不能通过使用自适应 UI 和尺寸类的单个故事板来处理这些布局差异吗?即将推出的 iOS 9 功能之一是拆分视图(覆盖或并排应用程序),因此您的“iPad”视图控制器可能会发现自己需要支持紧凑模式。
  • 在普通应用程序中,iPad 不仅仅是 iPhone 的可调整大小版本。您需要在 iPad 上明智地使用额外空间(添加额外控件),因此在这种情况下,单个 xib/storyboard 文件不适合 ipad 和 ipad。
  • 正确。 iPad 不仅仅是 iPhone 的可调整大小版本。它的布局不同。但自适应 UI 旨在完全满足您的需求。一个情节提要可以包含 iPad 和 iPhone 布局,并且系统使用正确的布局,具体取决于尺寸等级。 Adaptive UI 的主旨是从设备方面的思考转变为水平和垂直大小的思考(UITraitCollection)。然后,您的应用可以适应任何事物,无论是 iPhone、iPad、纵向、横向、分屏等。
【解决方案2】:

您描述的行为不适用于纯 Swift 类型。在 Swift 中做类似的事情没有合适的 Swift 概念(至少我不知道)。

使用 Objective-C 运行时技巧时,在 Objective-C 中实现这些技巧似乎是可以的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-20
    • 2016-01-28
    • 1970-01-01
    相关资源
    最近更新 更多