Установщик вычисляемых переменных внутри другого установщика вычисляемых переменных приводит к сбою приложения - PullRequest
0 голосов
/ 03 мая 2018

Этот код приводит к сбою где-то позже с EXC_BAD_ACCESS

SomeLoader().selectedIndex = 1    

class SomeLoader {

        // MARK: - Public

        var selectedIndex: Int? {
            get {
                return dataStorage.selectedIndex
            }
            set {
                dataStorage.selectedIndex = newValue
            }
        }
    }

этот код не разбился:

SomeLoader().selectedIndex = 1    

    class SomeLoader {

            // MARK: - Public

            var selectedIndex: Int? {
                get {
                    return dataStorage.selectedIndex
                }
                set {
                    dataStorage.updateSelected(index: newValue)
                }
            }
        }

где:

struct DataStorage<T: Hashable> {
    enum Keys: String {
        case selectedIndex
    }
    private func get<U>(forKey key: String) -> U? {
        guard let objectData = getData(forKey: key) else {
            return nil
        }
        let object: U? = get(forData: objectData)
        return object
    }
    private func get<U>(forData objectData: Data) -> U? {
        return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
    }
    private func save<U>(forKey key: String, object: U) {
        let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
        UserDefaults.standard.set(encodedData, forKey: key)
    }
}
extension DataStorage {
    func updateSelected(index: Int?) {
        guard let index = index else {
            remove(forKey: Keys.selectedIndex.rawValue)
            return
        }
        saveSelected(index: index)
    }
    var selectedIndex: Int? {

        get {
            return get(forKey: Keys.selectedIndex.rawValue)
        }
        set {
            guard let index = newValue else {
                remove(forKey: Keys.selectedIndex.rawValue)
                return
            }
            saveSelected(index: index)
        }
    }
 }

Почему? Это ошибка?

Скриншоты с ошибкой и стеком вызовов. Ошибка появляется позже в другой части кода.

enter image description here

enter image description here

Приведенный ниже код вылетает в iOS. Но работает на детской площадке.

//: Playground - noun: a place where people can play

import UIKit

struct DataStorage<T: Hashable> {
    enum Keys: String {
        case selectedIndex
    }
    private func get<U>(forKey key: String) -> U? {
        guard let objectData = getData(forKey: key) else {
            return nil
        }
        let object: U? = get(forData: objectData)
        return object
    }
    private func get<U>(forData objectData: Data) -> U? {
        return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
    }
    private func save<U>(forKey key: String, object: U) {
        let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
        UserDefaults.standard.set(encodedData, forKey: key)
    }
    private func remove(forKey key: String) {
        UserDefaults.standard.removeObject(forKey: key)
    }
    private func saveSelected(index: Int) {
        save(forKey: Keys.selectedIndex.rawValue, object: index)
    }
    private func getData(forKey key: String) -> Data? {
        return getContent(forKey: key) as? Data
    }
    private func getContent(forKey key: String) -> Any? {
        return UserDefaults.standard.value(forKey: key)
    }
}
extension DataStorage {
    func updateSelected(index: Int?) {
        guard let index = index else {
            remove(forKey: Keys.selectedIndex.rawValue)
            return
        }
        saveSelected(index: index)
    }
    var selectedIndex: Int? {

        get {
            return get(forKey: Keys.selectedIndex.rawValue)
        }
        set {
            guard let index = newValue else {
                remove(forKey: Keys.selectedIndex.rawValue)
                return
            }
            saveSelected(index: index)
        }
    }
}

class SomeLoader {

    // MARK: - Public
    var dataStorage = DataStorage<Int>()
    var selectedIndex: Int? {
        get {
            return dataStorage.selectedIndex
        }
        set {
            dataStorage.selectedIndex = newValue
        }
    }
}

let someLoader = SomeLoader()
someLoader.selectedIndex = 1
print(someLoader)

Код ниже работает везде

//: Playground - noun: a place where people can play

import UIKit

struct DataStorage<T: Hashable> {
    enum Keys: String {
        case selectedIndex
    }
    private func get<U>(forKey key: String) -> U? {
        guard let objectData = getData(forKey: key) else {
            return nil
        }
        let object: U? = get(forData: objectData)
        return object
    }
    private func get<U>(forData objectData: Data) -> U? {
        return NSKeyedUnarchiver.unarchiveObject(with: objectData) as? U
    }
    private func save<U>(forKey key: String, object: U) {
        let encodedData = NSKeyedArchiver.archivedData(withRootObject: object)
        UserDefaults.standard.set(encodedData, forKey: key)
    }
    private func remove(forKey key: String) {
        UserDefaults.standard.removeObject(forKey: key)
    }
    private func saveSelected(index: Int) {
        save(forKey: Keys.selectedIndex.rawValue, object: index)
    }
    private func getData(forKey key: String) -> Data? {
        return getContent(forKey: key) as? Data
    }
    private func getContent(forKey key: String) -> Any? {
        return UserDefaults.standard.value(forKey: key)
    }
}
extension DataStorage {
    func updateSelected(index: Int?) {
        guard let index = index else {
            remove(forKey: Keys.selectedIndex.rawValue)
            return
        }
        saveSelected(index: index)
    }
    var selectedIndex: Int? {

        get {
            return get(forKey: Keys.selectedIndex.rawValue)
        }
        set {
            guard let index = newValue else {
                remove(forKey: Keys.selectedIndex.rawValue)
                return
            }
            saveSelected(index: index)
        }
    }
}

class SomeLoader {

    // MARK: - Public
    var dataStorage = DataStorage<Int>()
    var selectedIndex: Int? {
        get {
            return dataStorage.selectedIndex
        }
        set {
            dataStorage.updateSelected(index: newValue)
        }
    }
}

let someLoader = SomeLoader()
someLoader.selectedIndex = 1
print(someLoader)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...