Slide 1

Slide 1 text

High Performance Core Data HighPerformanceCoreData.com MatthewMorey.com | @xzolian

Slide 2

Slide 2 text

Agenda

Slide 3

Slide 3 text

Managed Object Context Managed Object Managed Object Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Main Queue

Slide 4

Slide 4 text

Memory Speed Less More Slow Fast

Slide 5

Slide 5 text

Memory Speed Less More Slow Fast

Slide 6

Slide 6 text

Memory Speed Less More Slow Fast

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Tools

Slide 10

Slide 10 text

#define TICK NSDate *startTime = [NSDate date] #define TOCK NSLog(@"Elapsed Time: %f", -[startTime timeIntervalSinceNow])

Slide 11

Slide 11 text

#define TICK NSDate *startTime = [NSDate date] #define TOCK NSLog(@"Elapsed Time: %f", -[startTime timeIntervalSinceNow]) ... TICK; [self methodYouWantToMeasure]; TOCK;

Slide 12

Slide 12 text

-com.apple.CoreData.SQLDebug [1,2,3]

Slide 13

Slide 13 text

-com.apple.CoreData.SQLDebug [1,2,3]

Slide 14

Slide 14 text

-com.apple.CoreData.SQLDebug [1,2,3]

Slide 15

Slide 15 text

-com.apple.CoreData.SQLDebug [1,2,3]

Slide 16

Slide 16 text

-com.apple.CoreData.SQLDebug [1,2,3] -com.apple.CoreData.SyntaxColoredLogging 1 -com.apple.CoreData.MigrationDebug 1 -com.apple.CoreData.SQLiteDebugSynchronous [0,1,2] -com.apple.CoreData.SQLiteIntegrityCheck [1] -com.apple.CoreData.ConcurrencyDebug [1,2,3]

Slide 17

Slide 17 text

$ sqlite3

Slide 18

Slide 18 text

$ sqlite3 UFO.sqlite sqlite> select * from sqlite_master; table|ZUFOSIGHTING|ZUFOSIGHTING|3|CREATE TABLE ZUFOSIGHTING ( Z_PK...VARCHAR ) table|Z_PRIMARYKEY|Z_PRIMARYKEY|4|CREATE TABLE Z_PRIMARYKEY (Z_ENT...INTEGER) table|Z_METADATA|Z_METADATA|5|CREATE TABLE Z_METADATA (Z_VERSION...BLOB)

Slide 19

Slide 19 text

sqlite> SELECT t0.ZSHAPE, COUNT( t0.ZSHAPE ) FROM ZUFOSIGHTING t0 GROUP BY t0.ZSHAPE; changed|1 changing|1546 chevron|760 cigar|1782 circle|5271 cone|265 ... teardrop|595 triangle|6082 unknown|4490

Slide 20

Slide 20 text

SQLite Professional Pony Debugger

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

Tools •Macros •Launch Arguments •SQL •Instruments •Measure, Measure, Measure

Slide 24

Slide 24 text

Fetching

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; [fetchRequest setFetchBatchSize:20];

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; NSArray *UFOSightingsArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; NSMutableDictionary *uniqueShapesDictionary = [NSMutableDictionary dictionary]; for (UFOSighting *sighting in UFOSightingsArray) { ... // Count unique shape items ... } NSManagedObject

Slide 30

Slide 30 text

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; [fetchRequest setResultType:NSDictionaryResultType]; [fetchRequest setPropertiesToFetch:@"shape"]; ... // Count unique shape items ... NSDictionaryResultType

Slide 31

Slide 31 text

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; [fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"shape == %@", @"sphere"]]; NSUInteger sphereCount = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error]; ... // Repeat for each unique shape ... countForFetchRequest:error:

Slide 32

Slide 32 text

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"count"]; [expressionDescription setExpression: [NSExpression expressionForFunction:@"count:" arguments: @[[NSExpression expressionForKeyPath:@"shape"]]]]; [fetchRequest setPropertiesToFetch:@[@"shape", expressionDescription]]; [fetchRequest setPropertiesToGroupBy:@[@"shape"]]; [fetchRequest setResultType:NSDictionaryResultType]; NSExpression

Slide 33

Slide 33 text

NSExpression NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init]; [expressionDescription setName:@"count"]; [expressionDescription setExpression: [NSExpression expressionForFunction:@"count:" arguments: @[[NSExpression expressionForKeyPath:@"shape"]]]]; [fetchRequest setPropertiesToFetch:@[@"shape", expressionDescription]]; [fetchRequest setPropertiesToGroupBy:@[@"shape"]]; [fetchRequest setResultType:NSDictionaryResultType];

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Prefetch Required Relationships

Slide 36

Slide 36 text

[fetchRequest setRelationshipKeyPathsForPrefetching: @[@"photo"]];

Slide 37

Slide 37 text

Fetch in the background

Slide 38

Slide 38 text

[backgroundContext performBlock:^{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; fetchRequest.resultType = NSManagedObjectIDResultType; NSArray *managedObjectIDs = [backgroundContext executeFetchRequest:fetchRequest error:nil]; [mainQueueContext performBlock:^{ for (NSManagedObjectID *managedObjectID in managedObjectIDs) { UFOSighting *UFOSighting = [mainQueueContext objectWithID:managedObjectID]; // // Update UI on main queue // } }]; }];

Slide 39

Slide 39 text

[backgroundContext performBlock:^{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; fetchRequest.resultType = NSManagedObjectIDResultType; NSArray *managedObjectIDs = [backgroundContext executeFetchRequest:fetchRequest error:nil]; [mainQueueContext performBlock:^{ for (NSManagedObjectID *managedObjectID in managedObjectIDs) { UFOSighting *UFOSighting = [mainQueueContext objectWithID:managedObjectID]; // // Update UI on main queue // } }]; }];

Slide 40

Slide 40 text

[backgroundContext performBlock:^{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; fetchRequest.resultType = NSManagedObjectIDResultType; NSArray *managedObjectIDs = [backgroundContext executeFetchRequest:fetchRequest error:nil]; [mainQueueContext performBlock:^{ for (NSManagedObjectID *managedObjectID in managedObjectIDs) { UFOSighting *UFOSighting = [mainQueueContext objectWithID:managedObjectID]; // // Update UI on main queue // } }]; }];

Slide 41

Slide 41 text

[backgroundContext performBlock:^{ NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"UFOSighting"]; fetchRequest.resultType = NSManagedObjectIDResultType; NSArray *managedObjectIDs = [backgroundContext executeFetchRequest:fetchRequest error:nil]; [mainQueueContext performBlock:^{ for (NSManagedObjectID *managedObjectID in managedObjectIDs) { UFOSighting *UFOSighting = [mainQueueContext objectWithID:managedObjectID]; // // Update UI on main queue // } }]; }];

Slide 42

Slide 42 text

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:”MyEntity”]; NSAsynchronousFetchRequest *async = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest:request completionBlock^(id result) { if (result.finalResult) { ... } }]; [context performBlock: ^() { NSError *error = nil; asyncResult = [moc executeRequest:asyncRequest error:&blockError]; }]; iOS 8 | OS X Yosemite

Slide 43

Slide 43 text

Fetching •Don’t fetch more than you need •Set a batch size •Let SQLite do the calculations •Prefetch required relationships •Fetch in the background

Slide 44

Slide 44 text

Predicates

Slide 45

Slide 45 text

Light Comparisons First

Slide 46

Slide 46 text

[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"shape == %@ AND duration > %i", @"sphere", 30]];

Slide 47

Slide 47 text

[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"shape == %@ AND duration > %i", @"sphere", 30]]; [fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"duration > %i AND shape == %@", 30, @"sphere"]];

Slide 48

Slide 48 text

Be cautious with strings

Slide 49

Slide 49 text

Predicate Costs Less More Beginswith Endswith Equality == Contains Matches

Slide 50

Slide 50 text

Predicate Costs Less More Beginswith Endswith Equality == Contains Matches [cd] cost you even more

Slide 51

Slide 51 text

Predicates •Do light (numerical) comparisons first •Beginswith/Endswith instead of Contains/Matches •Don’t use [cd]

Slide 52

Slide 52 text

Searching

Slide 53

Slide 53 text

Canonicalize String Properties

Slide 54

Slide 54 text

Canonicalize String Properties Description canonicalizedDesc Green Mën green men BEAM beam Prόbë probe ABDUCTION abduction

Slide 55

Slide 55 text

CFStringNormalize((CFMutableStringRef)result, kCFStringNormalizationFormD); CFStringFold((CFMutableStringRef)result, kCFCompareCaseInsensitive | kCFCompareDiacriticInsensitive | kCFCompareWidthInsensitive, NULL);

Slide 56

Slide 56 text

Canonicalized Tokens

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

componentsSeperatedByCharactersInSet

Slide 60

Slide 60 text

Separate Stack

Slide 61

Slide 61 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Primary Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Search Tokens

Slide 62

Slide 62 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Primary Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Search Tokens URIRepresentation

Slide 63

Slide 63 text

Hash of Tokens

Slide 64

Slide 64 text

Searching •Canonicalize text properties •Use tokens •Separate persistence stack •Hash of tokens

Slide 65

Slide 65 text

Data Model

Slide 66

Slide 66 text

Don’t Overnormalize

Slide 67

Slide 67 text

Use External Storage

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

Data Model •Don’t overnormalize •Use external storage for large attributes •Large blobs as separate entity •Less data takes less time to fetch

Slide 73

Slide 73 text

App Launch

Slide 74

Slide 74 text

“Lots of Things” Problem

Slide 75

Slide 75 text

NSBatchUpdateRequest *batchRequest = [NSBatchUpdateRequest batchUpdateRequestWithEntityName: [RSSItem entityName]]; batchRequest.propertiesToUpdate = @{NSStringFromSelector(@selector(read)): [NSNumber numberWithBool:YES]}; batchRequest.resultType = NSStatusOnlyResultType; batchRequest.predicate = [NSPredicate predicateWithFormat:@"..."]; NSError *requestError; NSBatchUpdateResult *result = (NSBatchUpdateResult *)[self.managedObjectContext executeRequest:batchRequest error:&requestError]; if (result == nil) { NSLog(@"Error: %@", [requestError localizedDescription]); } else { // Batch update succeeded } iOS 8 | OS X Yosemite

Slide 76

Slide 76 text

Importing Data

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

Main Queue vs Private Queue self.managedObjectContext = self.persistenceStack.managedObjectContext; [self.managedObjectContext performBlockAndWait:^{ [self import]; }];

Slide 79

Slide 79 text

Main Queue vs Private Queue NSManagedObjectContext *privateManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; [privateManagedObjectContext setPersistentStoreCoordinator: self.managedObjectContext.persistentStoreCoordinator]; [privateManagedObjectContext performBlockAndWait:^{ [self import]; }];

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

Typical Import Algorithm 1) JSON to NSDictionary 2) Find existing NSManagedObject 3) Optionally, create new NSManagedObject 4) Set attributes of new/updated NSManagedObject 5) Repeat for every JSON item

Slide 82

Slide 82 text

Typical Import Algorithm 1) JSON to NSDictionary 2) Find existing NSManagedObject 3) Optionally, create new NSManagedObject 4) Set attributes of new/updated NSManagedObject 5) Repeat for every JSON item

Slide 83

Slide 83 text

Efficient Import Algorithm 1) Sort import objects by ID 2) Execute a single fetch request for all matching IDs 3) Iterate through both import and existing objects 4) Update or create

Slide 84

Slide 84 text

1 4 2 3 ... New Data

Slide 85

Slide 85 text

1 4 2 3 ... New Data 4 1 ... Existing Data

Slide 86

Slide 86 text

1 4 2 3 ... New Data 4 1 ... Existing Data

Slide 87

Slide 87 text

1 4 2 3 ... New Data 4 1 ... Existing Data

Slide 88

Slide 88 text

1 4 2 3 ... New Data 4 1 ... Existing Data

Slide 89

Slide 89 text

1 2 3 4 ... New Data 1 4 ... Existing Data Update

Slide 90

Slide 90 text

1 2 3 4 ... New Data 1 4 ... Existing Data Update

Slide 91

Slide 91 text

1 2 3 4 ... New Data 1 4 ... Existing Data Insert

Slide 92

Slide 92 text

1 2 3 4 ... New Data 1 4 ... Existing Data Insert

Slide 93

Slide 93 text

2 1 2 3 4 ... New Data 1 4 ... Existing Data

Slide 94

Slide 94 text

2 1 2 3 4 ... New Data 1 4 ... Existing Data

Slide 95

Slide 95 text

1 2 3 4 ... New Data 1 4 ... Existing Data 2

Slide 96

Slide 96 text

1 2 3 4 ... New Data 1 4 ... Existing Data 2 Insert

Slide 97

Slide 97 text

1 2 3 4 ... New Data 1 4 ... Existing Data 2 Insert

Slide 98

Slide 98 text

3 1 2 3 4 ... New Data 1 4 ... Existing Data 2

Slide 99

Slide 99 text

3 1 2 3 4 ... New Data 1 4 ... Existing Data 2

Slide 100

Slide 100 text

1 2 3 4 ... New Data 1 4 ... Existing Data 2 3 Update

Slide 101

Slide 101 text

1 2 3 4 ... New Data 1 4 ... Existing Data 2 3 Update

Slide 102

Slide 102 text

No content

Slide 103

Slide 103 text

Efficient Import Algorithm With Batching 1) Sort import objects by ID 2) Execute multiple fetch request for matching IDs - Iterate through both import and existing objects - Update or create 3) Save Batch

Slide 104

Slide 104 text

// Grab sorted persisted managed objects, based on the batch NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"UFOSighting"]; NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat: @"%K IN %@", @"GUID", jsonBatchGUIDArray];

Slide 105

Slide 105 text

// Grab sorted persisted managed objects, based on the batch NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"UFOSighting"]; NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat: @"%K IN %@", @"GUID", jsonBatchGUIDArray];

Slide 106

Slide 106 text

Pre-Populated SQLite File in App Bundle

Slide 107

Slide 107 text

Download Pre-Populated SQLite File

Slide 108

Slide 108 text

Importing Data •Do import work on private queues •Use efficient find-or-create algorithm •Work in batches to keep memory low •Use pre-populated SQLite file

Slide 109

Slide 109 text

Memory

Slide 110

Slide 110 text

[context refreshObject:UFOSightingManagedObject mergeChanges:NO];

Slide 111

Slide 111 text

[context reset];

Slide 112

Slide 112 text

Concurrency Models

Slide 113

Slide 113 text

Managed Object Context Managed Object Managed Object Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Main Queue

Slide 114

Slide 114 text

Managed Object Context Managed Object Managed Object Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Main Queue

Slide 115

Slide 115 text

Managed Object Context Managed Object Managed Object Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Main Queue

Slide 116

Slide 116 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue

Slide 117

Slide 117 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue

Slide 118

Slide 118 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue

Slide 119

Slide 119 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Context Did Save Notification Merge Changes From Notification

Slide 120

Slide 120 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Context Did Save Notification Merge Changes From Notification

Slide 121

Slide 121 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Context Did Save Notification Refetch and Reload

Slide 122

Slide 122 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue

Slide 123

Slide 123 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work

Slide 124

Slide 124 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work Persisting to Disk

Slide 125

Slide 125 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work Persisting to Disk

Slide 126

Slide 126 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work Persisting to Disk

Slide 127

Slide 127 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work Persisting to Disk

Slide 128

Slide 128 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Managed Object Context Private Queue UI Work Persisting to Disk

Slide 129

Slide 129 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue

Slide 130

Slide 130 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates

Slide 131

Slide 131 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates UI Work

Slide 132

Slide 132 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates UI Work Persisting to Disk

Slide 133

Slide 133 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates UI Work Persisting to Disk

Slide 134

Slide 134 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates UI Work Persisting to Disk

Slide 135

Slide 135 text

Persistent Store Coordinator Persistent Store Model Main Queue Managed Object Context Private Queue Managed Object Context Managed Object Context Private Queue Background Updates UI Work Persisting to Disk __block NSManagedObjectContext *temporaryContext = self.workerObjectContext; __block NSManagedObjectContext *managedObjectContext = self.managedObjectContext; __block NSManagedObjectContext *writerObjectContext = self.writerManagedObjectContext; [temporaryContext performBlock:^{ NSError *error = nil; if (![temporaryContext save:&error]) { // TODO: Handle error } [managedObjectContext performBlock:^{ NSError *error = nil; if (![managedObjectContext save:&error]) { // TODO: Handle error } [writerObjectContext performBlock:^{ NSError *error = nil; if (![writerObjectContext save:&error]) { // TODO: Handle error } // Success!!! }]; // writerObjectContext }]; // managedObjectContext }]; // temporaryContext

Slide 136

Slide 136 text

No content

Slide 137

Slide 137 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model

Slide 138

Slide 138 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model

Slide 139

Slide 139 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model

Slide 140

Slide 140 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model

Slide 141

Slide 141 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model Context Did Save Notification

Slide 142

Slide 142 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model Context Did Save Notification Merge Changes From Notification

Slide 143

Slide 143 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model Context Did Save Notification Merge Changes From Notification

Slide 144

Slide 144 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model Context Did Save Notification Refetch and Reload

Slide 145

Slide 145 text

No content

Slide 146

Slide 146 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Persistent Store Coordinator Model Context Did Save Notification Refetch and Reload •Cannot pass objects between persistent store coordinators •Cannot pass objectIDs between persistent store coordinators •You can use URIRepresentation •You can use mergeChangesFromContextDidSaveNotification

Slide 147

Slide 147 text

TLDR

Slide 148

Slide 148 text

Managed Object Context Persistent Store Coordinator Persistent Store (SQLite, XML, ...) Model Managed Object Context Main Queue Private Queue Context Did Save Notification Refetch and Reload

Slide 149

Slide 149 text

Concurrency Models •Use the simplest model that meets your needs •Update main context after large imports have completed

Slide 150

Slide 150 text

Bang Head Here

Slide 151

Slide 151 text

In general... •Use the tools, and measure, measure, measure •Don’t load more than you need to •Don’t use [cd] •Be smart with your data model •Import on a private queue in batches •Pick the correct (but simplest) concurrency model

Slide 152

Slide 152 text

Questions? HighPerformanceCoreData.com MatthewMorey.com | @xzolian BuoyExplorer.com - Marine Conditions App WristPresenter.com - Presentation App ChaiOne.com - Hiring remote iOS engineers