我的便利init在扩展中不起作用

时间:2016-09-30 21:00:12

标签: ios swift initialization

我正在重构UIViewController以删除那些不应该存在的非UI内容。我一直在关注Andy Matuschak's great talk about this,在一个例子中,他正在扩展NSPredicate并移动逻辑,从视图控制器中找出谓词应该是什么,并将其设置为fetchRequest.predicate结果。

我正在尝试做同样的事情,但我在扩展程序的便利init中遇到错误:

import Foundation

extension NSPredicate { 
    convenience init(forLiftLogFilter) { // it doesn't like this line
        if let logFilter = UserDefaultsManager.sharedInstance.logFilter?.rawValue {
            filterPredicate = NSPredicate(format: "lift.liftName = [c] %@", logFilter)
        } else {
            filterPredicate = nil
        }  
    }
}

我将从'UIViewController'中调用它,如下所示:

  override func viewWillAppear(animated: Bool) {
        let filterPredicate = NSPredicate.forLiftLogFilter // thinks NSPredicate doesn't have a member named 'forLiftLogFilter'
        reloadData(filterPredicate)

    super.viewWillAppear(animated)
  }

在我的情况下,我不需要传递任何初始化参数,但我很确定我需要一个forLiftLogFilter的外部名称,以便我可以进行调用。 Xcode(8.0 / Swift 2.3)告诉我'未命名的参数必须用空名'_'写。我理解错误,但我实际上没有任何参数。必须认为forLiftLogFilter是一个参数或其他东西。当然,由于这不起作用,在我正在调用的UIViewController中,我告诉我'Type NSPredicate没有成员'forLiftLogFilter'。

我做了很多关于扩展,初始化程序等的阅读,但没有关于名称但没有参数的便利初始化程序的答案。

任何人都可以帮我理解我的初始化程序有什么问题吗?

为了比较,这是Andy在他的演示中使用的代码

extension NSPredicate {
    convenience init(forTasksWithinNumberOfDays numberOfDays: Int, ofDate: Date, calendar: NSCalendar = NSCalendar.currentCalendar()) {
    self.init(format: "dueDate = %@" argumentArray: [calendar.dateByAddingUnit(.day, value: numberOfDays, toDate: date, options: NSCalendarOptions())!] 
  }
}

他从像这样的视图控制器调用它:

override func viewDidLoad() {
    super.viewDidLoad()

    fetchRequest.predicate = NSPredicate(forTasksWithinNumberOfDays: 10, ofDate: NSDate()) 

我已添加此内容以显示我认为需要遵循的结构...

2 个答案:

答案 0 :(得分:0)

听起来你正在尝试创建一个返回NSPredicate实例的类方法。

您的扩展程序必须是这样的:

import Foundation

extension NSPredicate { 
    static func forLiftLogFilter() -> NSPredicate? {
        if let logFilter = UserDefaultsManager.sharedInstance.logFilter?.rawValue {
            return NSPredicate(format: "lift.liftName = [c] %@", logFilter)
        } else {
            return nil
        }  
    }
}

现在您可以正确调用此类方法:

let filterPredicate = NSPredicate.forLiftLogFilter

答案 1 :(得分:0)

您不需要便利初始化程序。

致电

    var filterPredicate: NSPredicate = nil
    if let logFilter = UserDefaultsManager.sharedInstance.logFilter?.rawValue {
            filterPredicate = NSPredicate(format: "lift.liftName = [c] %@", logFilter)
    }

无论何时需要它。

或者,如果您希望它用于类范围:

private lazy var filterPredicate: NSPredicate = {
    if let logFilter = UserDefaultsManager.sharedInstance.logFilter?.rawValue {
        return NSPredicate(format: "lift.liftName = [c] %@", logFilter)
    }
    return nil
}