             
         case .Initial:
             
-            defer { self.state = .Loaded }
-            
             // fetch from cache
             do { try self.fetchedResultsController.performFetch() }
                 
             catch { fatalError("Could not fetch from managed object context. \(error)") }
             
-        case .Loaded: break
-        }
-        
-        // reset cursor
-        self.queryCursor = nil
-        
-        // fetch from server
-        self.store.search(.Query(query), resultsLimit: queryResultsLimit, zoneID: zoneID) { [weak self] (response: ErrorValue<([T], CKQueryCursor?)>) in
-            
-            guard let controller = self else { return }
-            
-            switch response {
-                
-            case let .Error(error):
-                
-                controller.event.didRefresh(error: error)
-                
-            case let .Value(_, cursor):
-                
-                controller.queryCursor = cursor
-                
-                controller.event.didRefresh(error: nil)
-            }
+            // set initial values
+            self.searchResults = self.fetchedResultsController.fetchedObjects as! [NSManagedObject]
+            
+            // send events
+            self.event.willChangeContent()
+            
+            for (index, _) in self.searchResults.enumerate() {
+                
+                self.event.didInsert(index: index)
+            }
+            
+            self.state = .Loaded
+            
+            fallthrough
+            
+        case .Loaded:
+            
+            // reset cursor
+            self.queryCursor = nil
+            
+            self.state = .Refreshing
+            
+            // fetch from server
+            self.store.search(.Query(query), resultsLimit: queryResultsLimit, zoneID: zoneID) { [weak self] (response: ErrorValue<([T], CKQueryCursor?)>) in
+                
+                guard let controller = self else { return }
+                
+                switch response {
+                    
+                case let .Error(error):
+                    
+                    controller.event.didRefresh(.Error(error))
+                    
+                    controller.state = .Loaded
+                    
+                case let .Value(results, cursor):
+                    
+                    // set cursor
+                    controller.queryCursor = cursor
+                    
+                    controller.event.didRefresh(.Value(results))
+                    
+                    controller.state = .Loaded
+                }
+            }
+            
+        case .Refreshing: return // ignore, already refreshing
+            
+        case .LoadingCursor: return // ignore, loading more
         }
     }
     

        forChangeType type: NSFetchedResultsChangeType,
        newIndexPath: NSIndexPath?) {
            
            switch type {
                
            case .Insert:

    /// The cached search results.
    public private(set) var searchResults = [NSManagedObject]()
    
    public private(set) var state = QueryResultsControllerState()
    
    public var event = QueryResultsControllerEvent<T>()
    
    // MARK: - Private Properties
    
