Как объявить переменную в swift, тип данных которой представляет собой массив сущностей, не зная, какая сущность? - PullRequest
0 голосов
/ 03 ноября 2018

Я создаю приложение для iOS с Xcode и использую CoreData. В модели данных есть несколько сущностей, скажем: A, B, C, D, E.

В homeViewController есть пять кнопок, и каждая кнопка выполняет переход к detailTableViewController для каждой сущности.

В зависимости от того, какая кнопка нажата, вы должны получить информацию для соответствующего объекта. Например, если я нажму кнопку «B», я должен получить данные для объекта «B» в detailTableViewController.

И тут возникает вопрос: как я могу объявить переменную "entityArray", чтобы сохранить результат запроса выборки, если я не знаю, какая сущность будет нажата до нажатия кнопки? Я не имею представления о его типе данных, пока кнопка не будет нажата.

Если бы существовала только одна сущность "А", я бы написал:

let entitiesArray = [A]()
let request: NSFetchRequest<A> = A.fetchRequest()
entitiesArray = try context.fetch(request)
...

Однако я не знаю сущность, которую будут толкать.

И использование оператора switch в viewDidLoad не решает проблему, потому что мне нужно, чтобы entityArray был глобальной переменной, чтобы использовать ее внутри других функций, таких как numberOfRowsInSection и cellForRowAt indexPath.

Ответы [ 2 ]

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

Альтернативой использованию суперкласса NSManagedObject может быть создание протокола и объявление в вашем массиве объектов этого протокола. Это может иметь смысл, если вы хотите получить доступ к данным одинаковым образом для всех объектов в вашем пользовательском интерфейсе, например, получить имя, идентификатор и т. Д., И желательно, если они неизменны

Вот краткий пример использования встроенного протокола CustomStringConvertible

let entitesArray = [CustomStringConvertible]()

реализовать протокол в расширении

extension A: CustomStringConvertible {
    var description: String {
        return "\(someAttribute), \(someOtherAttribute)"
    }
}

Вы можете иметь простой протокол с заголовком и URL-адресом и позволить всем сущностям реализовывать этот протокол, вам нужно иметь разные имена в протоколе для атрибутов, чтобы они не конфликтовали с атрибутами в сущностях. Пример

protocol LabelSupport {
    var titleLabel: String { get }
    var urlLabel: String { get }
}

И пусть А реализует это

extension A: LabelSupport {
    var titleLabel: String {
        return title
    }
    var urlLabel: String {
        return url
        // or perhaps url.path or similar
    }
}
0 голосов
/ 03 ноября 2018

Добавьте это в свой контекст через расширение:

func fetchMOs (_ entityName: String, sortBy: [NSSortDescriptor]? = nil, predicate: NSPredicate? = nil) throws -> [NSManagedObject] {

      let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)

      request.returnsObjectsAsFaults = false //as I need to access value
      request.predicate = predicate
      request.sortDescriptors = sortBy
      return try! self.fetch(request) as! [NSManagedObject]
}

тогда вы просто называете это так:

let mos = context.fetchMOs(String(describing: yourClassofAorBorCorD))

Дело в том, что в качестве типа результата используется удобная инициализация NSFetchRequest (: entityName) и структура NSFetchRequestResultType.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...