NSURLCache, RestKit, Stopping in the Debugger, and Evil Orphaned Objects

  • AUTHOR: truelson
  • February 20, 2014
NSURLCache, RestKit, Stopping in the Debugger, and Evil Orphaned Objects

Spent a day trying to understand why RestKit wasn’t deleting orphaned CoreData objects after receiving the updated object graph from the server. Yep, it involved caching and a problem that only showed up during development.

RestKit saves every GET request to NSURLCache, but upon inspection, I realized it was skipping cleanup of objects where I knew storeCachedResponse:forRequest had been called but now was returning an even older cached response. It seems NSURLCache doesn’t correctly save to disk upon storing the request, so if you stop the app early in the debugger, there’s a chance you will later use an old cache and not the latest one. Then, upon another new request, if the old cache’s Etag/body is the same as the latest response’s Etag/body, then RestKit thinks it doesn’t need to run a cleanup since RestKit thinks it has the same object graph as the last request. For example, if I create an object on the server, run the app, stop the app in the debugger after the app has fetched the latest object graph from the server, then delete the object on the server, then run the app again, my app will often have the object and RestKit won’t delete it, since both the latest request and the cached request look the same, and RestKit gets to say, “I don’t need to do any work.” And this only happens every now and then. Oy.

When I don’t close the app by hitting the debugger stop button, I haven’t been able to reproduce it, so there’s some sort of cleanup that doesn’t occur when you hit the stop button. I watched the modifications on Cache.db-shm and Cache.db-wal, and it WAS saving to disk with each storeCachedResponse:forRequest, but evidently not correctly sometimes as the problem would still show itself.

What an ugly bug… fortunately seems to only happen when I’m developing, though.