Slide 1

Slide 1 text

ACCESSING DATA JASDEV SINGH

Slide 2

Slide 2 text

FETCH REQUESTS THEY DO A LOT

Slide 3

Slide 3 text

LET'S DECONSTRUCT THESE TWO STATEMENTS let request = NSFetchRequest(entityName: "Chain") let chains = try! moc.executeFetchRequest(request)

Slide 4

Slide 4 text

STEPS ▸ Context forwards the request to its persistent store coordinator (passes itself as a parameter) ▸ Persistent store coordinator forwards the request to all of its persistent stores (passing through the context from the first step) ▸ The persistent store converts the fetch request to a SQL statement and sends this query to SQLite.

Slide 5

Slide 5 text

STEPS CONTINUED ▸ SQLite executes the query on the database files and returns all rows matching the query. Rows contain object IDs, which are used in the persistent store's row cache with an associated "last updated" timestamp. ▸ The persistent store instantiates managed objects for the object IDs1. 1 Core Data performs uniquing, which guarantees that only a single object representing a certain piece of data exists within a context.

Slide 6

Slide 6 text

ALMOST THERE ▸ The persistent store coordinator returns an array of objects to the context. ▸ Pending changes are applied and results are updated accordingly. ▸ Final array of managed objects is returned to the caller

Slide 7

Slide 7 text

OVERVIEW

Slide 8

Slide 8 text

HOW CAN WE HANDLE LARGE DATASETS IN MEMORY? FAULTING

Slide 9

Slide 9 text

FAULTS Lightweight objects that are not populated with actual data yet2. 2 Can customize this behavior with the returnsObjectsAsFaults property on NSFetchRequest

Slide 10

Slide 10 text

ACCESSING PROPERTIES ON A FAULT ▸ Core Data's property accessor calls willAccessValueForKey(_:) ▸ Context asks the persistent store coordinator to fulfill the fault. ▸ Coordinator asks the store for the data associated with the object ID by calling newValuesForObjectWithID(_:withContext:).

Slide 11

Slide 11 text

ACCESSING PROPERTIES ON A FAULT, CONTINUED ▸ Store consults row cache. If found, returns. Else, SQL query is made and executed. Results from a query, if needed, updates the row cache. ▸ Context materializes the object from the results that are returned to it.

Slide 12

Slide 12 text

OVERVIEW

Slide 13

Slide 13 text

FETCH REQUEST RESULT TYPES ▸ Object IDs3 ▸ Managed Objects ▸ Specific properties as dictionaries ▸ Count 3 Will still fetch all values for each object into the store's row cache. To disable this, set includesPropertyValues to false on the fetch request. We use this flag in ! for delete queries that fetch then delete to improve performance.

Slide 14

Slide 14 text

Batching ▸ Batch size can be set via fetchBatchSize on NSFetchRequest4 ▸ Core Data loads pages around whatever indices you access in the result of the fetch request5. 5 NSFetchRequest also has an asynchronous variant, NSAsynchronousFetchRequest. This variant hooks up nicely with NSProgress. 4 The only use of fetchBatchSize in ! is in TMTimelineAndBlogDataSource and it's set to zero (no batching) " But, we make heavy use of fetchLimit.

Slide 15

Slide 15 text

Relationships ▸ To avoid pulling in the whole object graph on a fetch requests, relationships are handled through faulting. ▸ To-one relationships use simple object ID faulting ▸ To-many relationships use faulting and only materializes relations on property access.

Slide 16

Slide 16 text

Memory Concerns When hitting memory warnings (or app backgrounding), it's common to re-fault all objects by making a call to refreshAllObjects. This also breaks any relationship reference cycles.

Slide 17

Slide 17 text

TAKEAWAYS ▸ Fetch requests take round trips, use row caches, and return faults by default ▸ Accessing a property on a fault causes it to be materialized ▸ Fetch requests can have different result types (count, Object IDs, managed objects, and attribute dictionaries) ▸ Use batching when possible