2014-09-21 8 views
19

Любые советы по реализации рассчитанных атрибутов при использовании Core Data в Swift?Усилители атрибутов CoreData Swift и переходных атрибутов

с сгенерированным классом ManagedObject, я пытался переопределить геттер, но я получаю сообщение об ошибке:

'NSManaged' not allowed on computed properties

, который означает, что вы не можете переопределить геттер для переходного (вычисленного) атрибута.

В приведенном ниже примере кода dateDue определяется как переходный атрибут в моей модели.

Обратите внимание, что @NSManaged lines были созданы Xcode - не добавлены мной.

@NSManaged var timeStamp: NSDate 
@NSManaged var dateDue: String { 
    get { 

     self.willAccessValueForKey("dateDue") 
     var ddtmp = self.primitiveValueForKey("dateDue") as String? 
     self.didAccessValueForKey("dateDue") 

     if (ddtmp == nil) 
     { 

      let calendar = NSCalendar.currentCalendar() 

      let components = calendar.components((NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit) , fromDate: self.timeStamp) 
      ddtmp = "\(components.year * 1000 + components.month)" 
      self.setPrimitiveValue(ddtmp, forKey: "dateDue") 

     } 



     return ddtmp! 
    } 

} 

ответ

5

«Переходный» и «вычисленный» в том смысле, что вы имеете в виду разные вещи и являетесь взаимоисключающими.

Transient означает, что значение хранится в памяти на графе объектов. Вычисление означает, что значение не хранится нигде и рассчитывается в геттере. Оба они отличаются от классического непереходного атрибута , который хранится на графе объектов и сохраняется на диске.

@NSManaged может применяться только к атрибутам, имеющим слот в модели управляемого объекта.

+0

Это атрибут в модели управляемого объекта. Juts для расширения, я пытаюсь скопировать метод, используемый одной из программ выборки яблока - однако образец яблока был написан в Objective C - фактически это его шаблон, который поставляется в Xcode (приложение основных деталей). –

+0

Да, но ObjC не делает '@ NSManaged' - если вы пытаетесь обернуть базовый атрибут, вы не должны использовать' @ NSManaged' здесь. '@ NSManaged' сообщает компилятору, что реализация свойства будет предоставлена ​​с опозданием во время выполнения. Использование '@ NSManaged', явно предоставляя реализацию, является противоречием. – iluvcapra

+0

ОК спасибо. Я передумаю удаление NSManaged. Дайте знать, как я нахожусь :) –

1

Удалить атрибут NSManaged.

+0

Nope. Извините, не это. Эта часть кода была сгенерирована Xcode, поэтому я полагаю, что она правильна (или, по крайней мере, в виде яблока). –

+1

не принимайте;) если он временный, он не управляется. поэтому либо примените, либо вы допустили ошибку. –

+0

Xcode сгенерировал код, но вы пишете метод, который скрывает базовый атрибут, вы и генератор кода думают о разных вещах. – iluvcapra

44

Во-первых, в модели данных создать переходный атрибут (section). Поскольку он является временным, он физически не хранится и, следовательно, не сохраняется в контексте управляемого объекта.

Атрибут section показано здесь:

enter image description here

Субъект показано здесь:

enter image description here

Класс NSManagedObject подкласс должен вычисляться атрибут 'раздел'. NSManagedObject подкласса, демонстрирующий, как выполнить это показано здесь:

class Number: NSManagedObject { 

    @NSManaged var number: NSNumber 

    var section: String? { 
     return number.intValue >= 60 ? "Pass" : "Fail" 
    } 
} 

Затем вы должны установить sectionForKeyPath в инициализаторе NSFetchedResultsController быть переходным ключевым атрибутом в модели данных и именем кэша, если это необходимо.

override func viewDidLoad() { 
     super.viewDidLoad() 

     fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "section", cacheName: "Root") 
     fetchedResultsController?.delegate = self 
     fetchedResultsController?.performFetch(nil) 

     tableView.reloadData() 
} 

func fetchRequest() -> NSFetchRequest { 

    var fetchRequest = NSFetchRequest(entityName: "Number") 
    let sortDescriptor = NSSortDescriptor(key: "number", ascending: false) 

    fetchRequest.predicate = nil 
    fetchRequest.sortDescriptors = [sortDescriptor] 
    fetchRequest.fetchBatchSize = 20 

    return fetchRequest 
} 

В результате UITableViewController с оценками, отсортированных байпас или нарушающим динамически:

enter image description here

Я сделал пример проекта, который можно найти на GitHub.

+0

https://gist.github.com/ivangodfather/86e0c3a02644f3520955 – Godfather

+1

Работал для меня. :) Плохая часть этого решения заключается в том, что вам нужно отредактировать автоматически сгенерированный класс Core Data. Каждый раз, когда вы регенерируете, вы должны повторить изменения. Я поместил раздел в класс расширения, но мне все равно придется удалить раздел из сгенерированного класса после регенерации класса. –

+1

Этот ответ должен быть принят! Работала отлично для меня с датами вместо цифр. Предложение для каждого, кто пытается реализовать разделение разделов по дате, начиная с «DateSectionTitles» Пример образца Apple: вместо этого выполните этот ответ! Большое спасибо @Bluehound – cdf1982