Как узнать о KVC с помощью Swift 4.2 - PullRequest
0 голосов
/ 03 октября 2018

Я использую Xcode 10.0 с swift 4.2, чтобы узнать о кодировании значения ключа из «Программирование какао для OSX»

Меня попросили создать простой класс, который является подклассом NSObject.Коды ниже:

import Cocoa

class Student: NSObject {
    var name: String = ""
    var gradeLevel: Int = 0
}

let student1 = Student()


student1.setValue("Benny", forKeyPath: "name")

student1.setValue ("Benny", forKeyPath: "name")

Генерирует следующее сообщение об ошибке:

Выполнение было прервано, причина: EXC_BAD_INSTRUCTION (код = EXC_I386_INVOP, субкод = 0x0).

Я посмотрел в Интернете и, кажется, некоторые проблемы, связанные с KVC, такие как: https://bugs.swift.org/browse/SR-5139

Что я делаю не так?Книга была издана в 2015 году.

1 Ответ

0 голосов
/ 03 октября 2018

В Swift 4 предоставление кода среде выполнения Objective C больше не выводится из соображений производительности.
Чтобы избежать сбоя, необходимо явно добавить атрибут @objc.

@objc var name: String = ""

Но с точки зрения сильного типа Swift есть два лучших способа получить значения с помощью KVC:

  1. Директива #keyPath, которая также использует среду выполнения ObjC, но проверяет ключпуть во время компиляции

    let keyPath = #keyPath(Student.name)
    student1.setValue("Benny", forKeyPath: keyPath)
    

    В этом случае вы получите очень описательное предупреждение компилятора

    Аргумент '#keyPath' ссылается на свойство 'name' в 'Student', которое зависитна вывод @objc устарел в Swift 4

  2. (рекомендуемый) собственный способ: Swift 4+ предоставляет свой собственный шаблон KVC, в котором не требуется подкласс NSObject.
    Ключевые пути обозначаются начальным обратным слешем, за которым следуют тип и свойство (или свойства):

    class Student {
        var name: String = ""
        var gradeLevel: Int = 0
    }
    
    let student1 = Student()
    student1[keyPath: \Student.name] = "Benny"
    
...