Как узнать о KVC с помощью swift 4.2

Я использую 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("Бенни", forKeyPath: "имя")

Выдает следующее сообщение об ошибке:

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

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

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


person hoboBob    schedule 03.10.2018    source источник
comment
Вы читали полный отчет об ошибке? Swift 4 больше не предоставляет свойства Objective-C по умолчанию, если только они не переопределяют что-либо или не удовлетворяют требованиям протокола. Используйте атрибут objc, чтобы предоставить их явным образом. Подробнее об этом можно прочитать в примечаниях к выпуску Xcode 9.   -  person Martin R    schedule 03.10.2018
comment
Привет, спасибо за ответ. Да, я прочитал полный отчет и подумал о том, чтобы прочитать примечания к выпуску Xcode 9. Отчет был за 2017 год. Я просто не хотел идти не в ту кроличью нору, гоняясь за вещами, и хотя лучше спросить.   -  person hoboBob    schedule 03.10.2018
comment
См. Выражение пути к ключу в книге Swift.   -  person rmaddy    schedule 04.10.2018


Ответы (1)


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

@objc var name: String = ""

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

  1. #P3#
    let keyPath = #keyPath(Student.name)
    student1.setValue("Benny", forKeyPath: keyPath)
    
    #P4# <цитата> #P5#
  2. Нативный (рекомендуемый) способ: Swift 4+ предоставляет собственный шаблон KVC, в котором создание подклассов NSObject не требуется.
    Пути к ключам обозначаются обратной косой чертой в начале, за которой следует тип и свойство (или свойства):

    class Student {
        var name: String = ""
        var gradeLevel: Int = 0
    }
    
    let student1 = Student()
    student1[keyPath: \Student.name] = "Benny"
    
person vadian    schedule 03.10.2018
comment
Это действительно интересный и отличный ответ... я приму предложение @Martin_R и прочитаю примечания к выпуску XC9... скоро! спасибо - person hoboBob; 04.10.2018
comment
Должен быть другой способ сделать это, который подходит для Swift. Синтаксис выглядит неправильно, обратная косая черта неуместна и не нужна - person hoboBob; 04.10.2018
comment
Посмотрите WWDC 2017: что нового в Foundation с 4:30. - person vadian; 04.10.2018
comment
Хорошо, вот 57 минут моей жизни ;) - person hoboBob; 04.10.2018
comment
Есть способы похуже тратить время жизни ???? Посмотрите видео и поймёте синтаксис - person vadian; 04.10.2018
comment
Прошла 21 минута, и я слушаю о КВО, о котором я действительно хотел спросить, но подумал, что не по теме. Спасибо, чувак :) действительно хорошее видео. Хотел бы я получить 30% того, о чем они говорят, но посмотрю снова через 1 месяц. У вас есть ссылка на больше? - person hoboBob; 04.10.2018