OSDN Git Service

#keyPathが使用可能な部分で全て使用するようにした
authormasakih <masakih@users.sourceforge.jp>
Tue, 28 Mar 2017 16:22:41 +0000 (01:22 +0900)
committermasakih <masakih@users.sourceforge.jp>
Tue, 28 Mar 2017 16:22:41 +0000 (01:22 +0900)
一部ビルド時にsegumentation faultが出るため除外

16 files changed:
KCD/AirBaseWindowController.swift
KCD/BridgeViewController.swift
KCD/BroserWindowController.swift
KCD/CollectionView.swift
KCD/DocksViewController.swift
KCD/ExternalBrowserWindowController.swift
KCD/FleetViewController.swift
KCD/ResourceViewController.swift
KCD/ShipDetailViewController.swift
KCD/ShipViewController.swift
KCD/SlotItemLevelView.swift
KCD/SlotItemWindowController.swift
KCD/StrengthenListItemCellView.swift
KCD/SuppliesView.swift
KCD/TimeSignalNotifier.swift
KCD/UpgradableShipsWindowController.swift

index de24185..93c28ce 100644 (file)
@@ -38,7 +38,7 @@ class AirBaseWindowController: NSWindowController {
         
         rId = 1
         
-        airBaseController.addObserver(self, forKeyPath: "content", context: nil)
+        airBaseController.addObserver(self, forKeyPath: #keyPath(airBaseController.content), context: nil)
         
         updateAreaRadio()
         updatePlaneSegment()
@@ -48,7 +48,7 @@ class AirBaseWindowController: NSWindowController {
                                of object: Any?,
                                change: [NSKeyValueChangeKey: Any]?,
                                context: UnsafeMutableRawPointer?) {
-        guard keyPath == "content" else {
+        guard keyPath == #keyPath(airBaseController.content) else {
             super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
             return
         }
index 8ad11a1..3b1d9a2 100644 (file)
@@ -25,10 +25,10 @@ class BridgeViewController: NSViewController {
         didSet {
             guard let representedObject = representedObject else { return }
             [
-                (NSContentArrayBinding, "screenshots"),
-                (NSSortDescriptorsBinding, "sortDescriptors"),
-                (NSSelectionIndexesBinding, "selectedIndexes"),
-                (NSFilterPredicateBinding, "filterPredicate")
+                (NSContentArrayBinding, #keyPath(ScreenshotModel.screenshots)),
+                (NSSortDescriptorsBinding, #keyPath(ScreenshotModel.sortDescriptors)),
+                (NSSelectionIndexesBinding, #keyPath(ScreenshotModel.selectedIndexes)),
+                (NSFilterPredicateBinding, #keyPath(ScreenshotModel.filterPredicate))
                 ]
                 .forEach {
                     arrayController.bind($0.0, to: representedObject, withKeyPath: $0.1, options: nil)
index 7ad54f7..d82468b 100644 (file)
@@ -37,7 +37,7 @@ class BroserWindowController: NSWindowController {
     }
     
     class func keyPathsForValuesAffectingFlagShipName() -> Set<String> {
-        return ["flagShipID"]
+        return [#keyPath(flagShipID)]
     }
     
     let managedObjectContext = ServerDataStore.default.context
@@ -117,7 +117,7 @@ class BroserWindowController: NSWindowController {
         fleetViewController.shipOrder = UserDefaults.standard.fleetViewShipOrder
         fleetViewController.enableAnimation = true
         
-        bind("flagShipID", to: deckContoller, withKeyPath: "selection.ship_0", options: nil)
+        bind(#keyPath(flagShipID), to: deckContoller, withKeyPath: "selection.ship_0", options: nil)
         
         NotificationCenter.default
             .addObserver(forName: .CombinedDidCange, object: nil, queue: nil) {
@@ -454,7 +454,7 @@ extension BroserWindowController {
         
         shipTypeSegment.bind(NSSelectedIndexBinding,
                              to: tabViewItemViewControllers[0],
-                             withKeyPath: "selectedShipType",
+                             withKeyPath: #keyPath(MainTabVIewItemViewController.selectedShipType),
                              options: nil)
         let o = selectedMainTabIndex
         selectedMainTabIndex = o
@@ -468,7 +468,7 @@ extension BroserWindowController {
             button.isHidden = !vc.hasShipTypeSelector
             self.shipTypeSegment.bind(NSSelectedIndexBinding,
                                       to: vc,
-                                      withKeyPath: "selectedShipType",
+                                      withKeyPath: #keyPath(MainTabVIewItemViewController.selectedShipType),
                                       options: nil)
         }
         return mainTouchBar
index 5a194e1..312e725 100644 (file)
@@ -13,10 +13,10 @@ class CollectionView: NSCollectionView {
     required init?(coder: NSCoder) {
         super.init(coder: coder)
         
-        self.addObserver(self, forKeyPath: "selectionIndexPaths", context: nil)
+        self.addObserver(self, forKeyPath: #keyPath(selectionIndexPaths), context: nil)
     }
     deinit {
-        self.removeObserver(self, forKeyPath: "selectionIndexPaths")
+        self.removeObserver(self, forKeyPath: #keyPath(selectionIndexPaths))
     }
     
     override func observeValue(forKeyPath keyPath: String?,
index f7bb6dd..f8fb2cf 100644 (file)
@@ -10,16 +10,16 @@ import Cocoa
 
 class DocksViewController: MainTabVIewItemViewController {
     deinit {
-        ["deck2Time", "mission2Name",
-         "deck3Time", "mission3Name",
-         "deck4Time", "mission4Name"]
+        [#keyPath(deck2Time), #keyPath(mission2Name),
+         #keyPath(deck3Time), #keyPath(mission3Name),
+         #keyPath(deck4Time), #keyPath(mission4Name)]
             .forEach { unbind($0) }
-        ["nDock1Time", "nDock1ShipName",
-         "nDock2Time", "nDock2ShipName",
-         "nDock3Time", "nDock3ShipName",
-         "nDock4Time", "nDock4ShipName"]
+        [#keyPath(nDock1Time), #keyPath(nDock1ShipName),
+         #keyPath(nDock2Time), #keyPath(nDock2ShipName),
+         #keyPath(nDock3Time), #keyPath(nDock3ShipName),
+         #keyPath(nDock4Time), #keyPath(nDock4ShipName)]
             .forEach { unbind($0) }
-        ["kDock1Time", "kDock2Time", "kDock3Time", "kDock4Time"]
+        [#keyPath(kDock1Time), #keyPath(kDock2Time), #keyPath(kDock3Time), #keyPath(kDock4Time)]
             .forEach { unbind($0) }
         
         ["selection", "selection.no", "content.battleCell"]
@@ -149,11 +149,11 @@ class DocksViewController: MainTabVIewItemViewController {
                                change: [NSKeyValueChangeKey: Any]?,
                                context: UnsafeMutableRawPointer?) {
         if keyPath == "selection" || keyPath == "content.battleCell" {
-            notifyChangeValue(forKey: "sortieString")
+            notifyChangeValue(forKey: #keyPath(sortieString))
             return
         }
         if keyPath == "selection.no" {
-            notifyChangeValue(forKey: "cellNumber")
+            notifyChangeValue(forKey: #keyPath(cellNumber))
             return
         }
         
@@ -162,29 +162,29 @@ class DocksViewController: MainTabVIewItemViewController {
     
     private func setupStatus() {
         let missionKeys = [
-            ("deck2Time", "mission2Name"),
-            ("deck3Time", "mission3Name"),
-            ("deck4Time", "mission4Name")
+            (#keyPath(deck2Time), #keyPath(mission2Name)),
+            (#keyPath(deck3Time), #keyPath(mission3Name)),
+            (#keyPath(deck4Time), #keyPath(mission4Name))
         ]
         zip(missionStates, missionKeys).forEach {
-            bind($0.1.0, to: $0.0, withKeyPath: "time", options: nil)
-            bind($0.1.1, to: $0.0, withKeyPath: "name", options: nil)
+            bind($0.1.0, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
+            bind($0.1.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
         }
         
         let ndockKeys = [
-            ("nDock1Time", "nDock1ShipName"),
-            ("nDock2Time", "nDock2ShipName"),
-            ("nDock3Time", "nDock3ShipName"),
-            ("nDock4Time", "nDock4ShipName")
+            (#keyPath(nDock1Time), #keyPath(nDock1ShipName)),
+            (#keyPath(nDock2Time), #keyPath(nDock2ShipName)),
+            (#keyPath(nDock3Time), #keyPath(nDock3ShipName)),
+            (#keyPath(nDock4Time), #keyPath(nDock4ShipName))
         ]
         zip(ndockStatus, ndockKeys).forEach {
-            bind($0.1.0, to: $0.0, withKeyPath: "time", options: nil)
-            bind($0.1.1, to: $0.0, withKeyPath: "name", options: nil)
+            bind($0.1.0, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
+            bind($0.1.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
         }
         
-        let kdockKeys = ["kDock1Time", "kDock2Time", "kDock3Time", "kDock4Time"]
+        let kdockKeys = [#keyPath(kDock1Time), #keyPath(kDock2Time), #keyPath(kDock3Time), #keyPath(kDock4Time)]
         zip(kdockStatus, kdockKeys).forEach {
-            bind($0.1, to: $0.0, withKeyPath: "time", options: nil)
+            bind($0.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
         }
     }
     
index 3121d1c..e4e74d2 100644 (file)
@@ -21,8 +21,8 @@ class ExternalBrowserWindowController: NSWindowController {
     let managedObjectContext = BookmarkManager.shared().manageObjectContext
     
     deinit {
-        webView.removeObserver(self, forKeyPath: "canGoBack")
-        webView.removeObserver(self, forKeyPath: "canGoForward")
+        webView.removeObserver(self, forKeyPath: #keyPath(webView.canGoBack))
+        webView.removeObserver(self, forKeyPath: #keyPath(webView.canGoForward))
     }
     
     @IBOutlet var webView: WebView!
@@ -104,8 +104,8 @@ class ExternalBrowserWindowController: NSWindowController {
     override func windowDidLoad() {
         super.windowDidLoad()
         
-        webView.addObserver(self, forKeyPath: "canGoBack", context: nil)
-        webView.addObserver(self, forKeyPath: "canGoForward", context: nil)
+        webView.addObserver(self, forKeyPath: #keyPath(webView.canGoBack), context: nil)
+        webView.addObserver(self, forKeyPath: #keyPath(webView.canGoForward), context: nil)
         webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
         webView.frameLoadDelegate = self
     }
@@ -113,11 +113,11 @@ class ExternalBrowserWindowController: NSWindowController {
                                of object: Any?,
                                change: [NSKeyValueChangeKey: Any]?,
                                context: UnsafeMutableRawPointer?) {
-        if keyPath == "canGoBack" {
+        if keyPath == #keyPath(webView.canGoBack) {
             goSegment.setEnabled(webView.canGoBack, forSegment: 0)
             return
         }
-        if keyPath == "canGoForward" {
+        if keyPath == #keyPath(webView.canGoForward) {
             goSegment.setEnabled(webView.canGoForward, forSegment: 1)
             return
         }
index 9955cf9..776a5f2 100644 (file)
@@ -143,7 +143,7 @@ class FleetViewController: NSViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        fleetController.bind("content", to:self, withKeyPath:"fleet", options:nil)
+        fleetController.bind("content", to:self, withKeyPath:#keyPath(fleet), options:nil)
         fleetController.addObserver(self, forKeyPath:"selection.name", context:nil)
         shipKeys.forEach {
             let keyPath = "selection.\($0)"
@@ -172,7 +172,7 @@ class FleetViewController: NSViewController {
         NotificationCenter.default
             .addObserver(forName: .DidPrepareFleet, object: nil, queue: nil) { [weak self] _ in
                 guard let `self` = self else { return }
-                self.notifyChangeValue(forKey: "fleetNumber")
+                self.notifyChangeValue(forKey: #keyPath(fleetNumber))
         }
     }
     override func observeValue(forKeyPath keyPath: String?,
@@ -194,15 +194,15 @@ class FleetViewController: NSViewController {
             if context == &shipsContext {
                 switch keyPath {
                 case "sakuteki_0":
-                    notifyChangeValue(forKey: "totalSakuteki")
+                    notifyChangeValue(forKey: #keyPath(totalSakuteki))
                 case "seiku":
-                    notifyChangeValue(forKey: "totalSeiku")
+                    notifyChangeValue(forKey: #keyPath(totalSeiku))
                 case "totalSeiku":
-                    notifyChangeValue(forKey: "totalCalclatedSeiku")
+                    notifyChangeValue(forKey: #keyPath(totalCalclatedSeiku))
                 case "lv":
-                    notifyChangeValue(forKey: "totalLevel")
+                    notifyChangeValue(forKey: #keyPath(totalLevel))
                 case "totalDrums":
-                    notifyChangeValue(forKey: "totalDrums")
+                    notifyChangeValue(forKey: #keyPath(totalDrums))
                 default: break
                 }
                 return
@@ -227,12 +227,12 @@ class FleetViewController: NSViewController {
         ships = array.flatMap { $0 }
         
         [String]()
-            .appended { "totalSakuteki" }
-            .appended { "totalSeiku" }
-            .appended { "totalCalclatedSeiku" }
-            .appended { "totalLevel" }
-            .appended { "totalDrums" }
-            .appended { "repairable" }
+            .appended { #keyPath(totalSakuteki) }
+            .appended { #keyPath(totalSeiku) }
+            .appended { #keyPath(totalCalclatedSeiku) }
+            .appended { #keyPath(totalLevel) }
+            .appended { #keyPath(totalDrums) }
+            .appended { #keyPath(repairable) }
             .forEach { notifyChangeValue(forKey: $0) }
     }
 }
index 3248f1a..b8324b3 100644 (file)
@@ -10,14 +10,14 @@ import Cocoa
 
 class ResourceViewController: NSViewController {
     class func keyPathsForValuesAffectingShipNumberColor() -> Set<String> {
-        return ["maxChara", "shipCount", "minimumColoredShipCount"]
+        return [#keyPath(maxChara), #keyPath(shipCount), #keyPath(minimumColoredShipCount)]
     }
     
     let managedObjectContext = ServerDataStore.default.context
     
     deinit {
-        unbind("maxChara")
-        unbind("shipCount")
+        unbind(#keyPath(maxChara))
+        unbind(#keyPath(shipCount))
     }
     
     @IBOutlet var shipController: NSArrayController!
@@ -42,7 +42,7 @@ class ResourceViewController: NSViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
-        bind("maxChara", to: basicController, withKeyPath: "selection.max_chara", options: nil)
-        bind("shipCount", to: shipController, withKeyPath: "arrangedObjects.@count", options: nil)
+        bind(#keyPath(maxChara), to: basicController, withKeyPath: "selection.max_chara", options: nil)
+        bind(#keyPath(shipCount), to: shipController, withKeyPath: "arrangedObjects.@count", options: nil)
     }
 }
index c3c47e8..9e92620 100644 (file)
@@ -44,20 +44,20 @@ class ShipDetailViewController: NSViewController {
     }
     deinit {
         NotificationCenter.default.removeObserver(self)
-        damageView.unbind("damageType")
-        supply.unbind("shipStatus")
+        damageView.unbind(#keyPath(DamageView.damageType))
+        supply.unbind(#keyPath(SuppliesView.shipStatus))
         [slot00Field, slot01Field, slot02Field, slot03Field]
-            .forEach { $0?.unbind("slotItemID") }
+            .forEach { $0?.unbind(#keyPath(SlotItemLevelView.slotItemID)) }
     }
     
     
     @IBOutlet weak var supply: SuppliesView!
     @IBOutlet weak var guardEscapedView: GuardEscapedView!
     @IBOutlet weak var damageView: DamageView!
-    @IBOutlet weak var slot00Field: NSTextField!
-    @IBOutlet weak var slot01Field: NSTextField!
-    @IBOutlet weak var slot02Field: NSTextField!
-    @IBOutlet weak var slot03Field: NSTextField!
+    @IBOutlet weak var slot00Field: SlotItemLevelView!
+    @IBOutlet weak var slot01Field: SlotItemLevelView!
+    @IBOutlet weak var slot02Field: SlotItemLevelView!
+    @IBOutlet weak var slot03Field: SlotItemLevelView!
     @IBOutlet var shipController: NSObjectController!
     
     dynamic var guardEscaped: Bool = false {
@@ -77,9 +77,13 @@ class ShipDetailViewController: NSViewController {
         
         damageView.setFrameOrigin(.zero)
         view.addSubview(damageView)
-        damageView.bind("damageType", to: shipController, withKeyPath: "selection.status", options: nil)
+        damageView.bind(#keyPath(DamageView.damageType),
+                        to: shipController,
+                        withKeyPath: "selection.status", options: nil)
         
-        supply.bind("shipStatus", to: shipController, withKeyPath: "selection.self", options: nil)
+        supply.bind(#keyPath(SuppliesView.shipStatus),
+                    to: shipController,
+                    withKeyPath: "selection.self", options: nil)
         
         guardEscapedView.setFrameOrigin(.zero)
         view.addSubview(guardEscapedView)
@@ -92,7 +96,7 @@ class ShipDetailViewController: NSViewController {
         let fields = [slot00Field, slot01Field, slot02Field, slot03Field]
         let keypath = ["selection.slot_0", "selection.slot_1", "selection.slot_2", "selection.slot_3"]
         zip(fields, keypath).forEach {
-            $0.0?.bind("slotItemID", to: shipController, withKeyPath: $0.1, options: nil)
+            $0.0?.bind(#keyPath(SlotItemLevelView.slotItemID), to: shipController, withKeyPath: $0.1, options: nil)
         }
     }
 }
index 4ebf254..5eaef16 100644 (file)
@@ -66,7 +66,7 @@ class ShipViewController: MainTabVIewItemViewController {
         }
         shipController.sortDescriptors = UserDefaults.standard.shipviewSortDescriptors
         shipController.addObserver(self, forKeyPath: NSSortDescriptorsBinding, context: nil)
-        shipController.addObserver(self, forKeyPath: "arrangedObjects", context: nil)
+        shipController.addObserver(self, forKeyPath: #keyPath(shipController.arrangedObjects), context: nil)
         
         let tableViews = [expTableView, powerTableView, power2TableView, power3TableView]
         tableViews
@@ -92,8 +92,8 @@ class ShipViewController: MainTabVIewItemViewController {
             UserDefaults.standard.shipviewSortDescriptors = shipController.sortDescriptors
             return
         }
-        if keyPath == "arrangedObjects" {
-            notifyChangeValue(forKey: "standardDeviation")
+        if keyPath == #keyPath(shipController.arrangedObjects) {
+            notifyChangeValue(forKey: #keyPath(standardDeviation))
             return
         }
         
index 9cd5dfe..e068120 100644 (file)
@@ -20,18 +20,18 @@ class SlotItemLevelView: NSTextField {
     override init(frame frameRect: NSRect) {
         slotItemController = NSObjectController()
         super.init(frame: frameRect)
-        self.bind("slotItemLevel", to: slotItemController, withKeyPath: "selection.level", options: nil)
-        self.bind("slotItemAlv", to: slotItemController, withKeyPath: "selection.alv", options: nil)
+        bind(#keyPath(slotItemLevel), to: slotItemController, withKeyPath: "selection.level", options: nil)
+        bind(#keyPath(slotItemAlv), to: slotItemController, withKeyPath: "selection.alv", options: nil)
     }
     required init?(coder: NSCoder) {
         slotItemController = NSObjectController()
         super.init(coder: coder)
-        self.bind("slotItemLevel", to: slotItemController, withKeyPath: "selection.level", options: nil)
-        self.bind("slotItemAlv", to: slotItemController, withKeyPath: "selection.alv", options: nil)
+        bind(#keyPath(slotItemLevel), to: slotItemController, withKeyPath: "selection.level", options: nil)
+        bind(#keyPath(slotItemAlv), to: slotItemController, withKeyPath: "selection.alv", options: nil)
     }
     deinit {
-        self.unbind("slotItemLevel")
-        self.unbind("slotItemAlv")
+        unbind(#keyPath(slotItemLevel))
+        unbind(#keyPath(slotItemAlv))
     }
     
     // MARK: - Variable
index 16d1768..246279a 100644 (file)
@@ -27,7 +27,7 @@ class SlotItemWindowController: NSWindowController {
     var showEquipmentType: Int {
         get { return UserDefaults.standard.showEquipmentType.rawValue }
         set {
-            notifyChangeValue(forKey: "showEquipmentTypeTitle") {
+            notifyChangeValue(forKey: #keyPath(showEquipmentTypeTitle)) {
                 UserDefaults.standard.showEquipmentType = ShowType(rawValue: newValue) ?? .all
             }
             slotItemController.fetchPredicate = filterPredicate
index e83257a..0079489 100644 (file)
@@ -11,31 +11,31 @@ import Cocoa
 class StrengthenListItemCellView: NSTableCellView {
     
     class func keyPathsForValuesAffectingSecondsShipList() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingRequiredEquipment01() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingRequiredEquipment02() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingRequiredEquipment03() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingTargetEquipment() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingRemodelEquipment() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingNeedsScrewString01() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingNeedsScrewString02() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     class func keyPathsForValuesAffectingNeedsScrewString03() -> Set<String> {
-        return ["objectValue"]
+        return [#keyPath(objectValue)]
     }
     
     private var item: StrengthenListEnhancementItem? {
index 41633a9..4cbd3c1 100644 (file)
@@ -11,7 +11,10 @@ import Cocoa
 fileprivate var pShipStatusContext: Int = 0
 
 class SuppliesView: NSControl {
-    private let observeKeys = ["fuel", "maxFuel", "bull", "maxBull"]
+    private let observeKeys = [ #keyPath(Ship.fuel),
+                                #keyPath(Ship.maxFuel),
+                                #keyPath(Ship.bull),
+                                #keyPath(Ship.maxBull)]
     private let suppliesCell: SuppliesCell
     
     override init(frame: NSRect) {
index c3727f3..16b15c2 100644 (file)
@@ -18,12 +18,12 @@ class TimeSignalNotifier: NSObject {
     override init() {
         super.init()
         registerTimer()
-        self.bind("notifyTimeBeforeTimeSignal",
+        self.bind(#keyPath(notifyTimeBeforeTimeSignal),
                   to: udController,
                   withKeyPath: "values.notifyTimeBeforeTimeSignal")
     }
     deinit {
-        self.unbind("notifyTimeBeforeTimeSignal")
+        self.unbind(#keyPath(notifyTimeBeforeTimeSignal))
     }
     
     dynamic var notifyTimeBeforeTimeSignal: Int = 0 {
index fad1061..82d3972 100644 (file)
@@ -21,7 +21,7 @@ class UpgradableShipsWindowController: NSWindowController {
     }
     
     class func keyPathsForValuesAffectingFilterPredicate() -> Set<String> {
-        return ["showLevelOneShipInUpgradableList", "showsExcludedShipInUpgradableList"]
+        return [#keyPath(showLevelOneShipInUpgradableList), #keyPath(showsExcludedShipInUpgradableList)]
     }
     
     private var excludeShiIDsCache: [Int] {
@@ -72,7 +72,7 @@ class UpgradableShipsWindowController: NSWindowController {
     var excludeShiIDs: [Int] {
         get { return (NSArray(contentsOf: excludeShipIDsSaveURL) as? [Int]) ?? [] }
         set {
-            notifyChangeValue(forKey: "filterPredicate") {
+            notifyChangeValue(forKey: #keyPath(filterPredicate)) {
                 (newValue as NSArray).write(to: excludeShipIDsSaveURL, atomically: true)
                 UpgradableShipsWindowController.excludeShiIDsCache = newValue
             }