Retrieve the total number of objects in a NSManagedObjectContext - cocoa-touch

Is there a way to find out the total number of objects in a NSManagedObjectContext? I can't do it easily with a NSFetchRequestas it won't span over different entities.
What am trying to do is to view the state of my NSManagedObjectContext for debugging purposes.

If you're looking for all the objects in an NSManagedObjectContext, you can use the registeredObjects property. Note that NSManagedObjectContext acts like a scratch pad so this only returns the objects in the NSManagedObjectContext, not all the items in the persistent store.

You'd have to grab context.persistentStoreCoordinator.managedObjectModel.entities then iterate through and do a suitable countForFetcgRequest:... for each, summing the total. If it's for debug logging I guess it's quite likely you'll end up wanting to do something with the full list of entities anyway.

Related

Reordering EKReminders

The EventKit framework provides methods which fetch an array of reminders/events for a given search predicate.
What I'm trying to figure out is the best way of reordering a UITableView with cells representing EKReminders. Besides reordering the table itself, what's the best way to handle remembering the order of the table?
I thought about storing an array in NSUserDefaults containing indexes corresponding to indexes of another array which contained the reminders. Then, you could rearrange the first array and then ask the second array for the reminder at the stored index.
I also considered storing pointers to EKReminder pointers in a similar manner, but that seemed useless given that the pointers would eventually be nil when the program ended, and if the pointers to pointers where stored, they'd no longer point to the same thing upon relaunch.
Any ideas?
Thanks.

NSArrayController vs NSMutableArray - When do you use a NSArrayController?

Working my way through one of my first Cocoa OS X projects where I'm grabbing remote XML data and storing objects in an NSMutableArray.
Today when I opened IB for the first time in the project I discovered the object NSArrayController.
Fairly basic question - When would I use one over the other? I am not using a TableView in my application and most things I read talk about binding it to a tabel view.
I am doing a bit of array manipulation though in that I add/remove/modify objects from the array at will. Is there a benefit to one over the other?
With what you described, create a custom data class. So each object of that class manipulates the data however you need and each object represents a record of data. Now with this if you wish to show your data, then subclass nsarraycontroller and bind to this. This controller can be setup to use the custom data class. If you are using the data internally, simply instatiate however many you wish and use NSSet. I recommend NSSet because it guarantee's uniqueness.
Hope this helps.
P.S. NSMutableSet also exists.

How to remove an object from NSMutableArray only when retain count reaches 0?

I know I'm not supposed to check or use retainCount, but I'm trying to wonder if there's a way to have an object be removed from an NSMutableArray only after its retain count is 0.
Basically, I want to add objects to an array, and have those objects be shared among other windows. When a window uses it, I want the retain count to go up by 1. When it's no longer used, I want it to go down. But, if some window is still using it, then I want it to be available to all other windows. When all windows are no longer using it, then I want it to be removed form the array and released entirely.
Thanks!
For the automatic removal from array on release you could use associated objects, as Dave DeLong described here:
How to add alive object to NSMutableArray and remove them when they're released?
But you'd probably be better off using an NSCountedSet, as it implements exactly what you're after. It just lacks item order.
To make up with the lack of item order you could use an additional NSMutableArray to keep order and add/remove items to/from it in sync with your counted set.

How does one effectively handle temporary objects in Core Data since the objectID changes between temporary objects and permanent objects?

What is the best way to handle temporary objects in Core Data? I've seen solutions where temporary contexts are created, where they are inserted into nil contexts, etc.
However, here's the issue I'm seeing in both of these solutions. I'm using Core Data for my object model and and in some of my views store a NSSet of Core Data objects. The problem I have is when the object is stored, the objectID changes which effectively invalidates anything stored in any NSSet since the isEqual and hash are now different. While I could invalidate the object stored in the NSSet, it often is not practical and certainly not always easy.
Here's the things I've considered:
1) override isEqual method and hash on NSManagedObject (obviously bad)
2) do not place any NSManagedObject in a NSSet (use a NSDictionary where the key is always fixed)
3) use an entirely different type to store in NSSet where I could correctly implement the isEqual and hash code methods
Does anyone have a better solution for this?
ManagedObjects in an NSSet -- that sounds like a Core Data relationship. Why not simply store your temporary managedObjects in a relationship, and have Core Data take care of the problems you're now running into. Then you can concentrate on when and how to delete the temporary objects, or break the relationship or whatever is needed.
However, here's the issue I'm seeing in both of these solutions. I'm using Core Data for my object model and and in some of my views store a NSSet of Core Data objects. The problem I have is when the object is stored, the objectID changes which effectively invalidates anything stored in any NSSet since the isEqual and hash are now different.
tjg184,
Your problem here is not the transition to permanent IDs but that your container class depends upon an immutable hash. Hence, change your container class to an array or dictionary and this problem goes away. (You give up uniquing with an array but that is easy to handle with a trip through a transient set to perform the uniquing.)
Andrew
A possible solution would be to convert the temporary IDs to permanent ones using [NSManagedObjectContext obtainPermanentIDsForObjects:error:].
But be aware that this may be expensive, especially if you have a lot of objects you need to process this way.
You could possibly subclass NSManagedObject and override the willSave and didSave methods to remove and then re-add you objects to your set.
I actually ended up using a different approach, that of using a NIL context and providing a base class to handle insertion into a context. It works really well and is the cleanest solution I have found. Code can be found here... Temporary Core Data

Is it ok to re-sort an array each time you need to access an element at a specific index?

I have a TableViewController that displays a list of elements CoreData relationship. In my cellForRowAtIndexPath:, I am getting a sortedArray from the set and then accessing the element at indexPath.row. Then in didSelectRowAtIndexPath:, I am doing the same thing.
Is this considered a bad practice? I see a theoretical danger in that if my sorting method returns a differently sorted array on a subsequent call, I could end up interacting with object B, even though the user clicked on the cell that showed object A. It shouldn't be possible for my sorting to return a differently sorted array, but I still feel that it is technically risky.
The only other way I know of to do this is to have my tableViewController keep it's own NSArray member, and when it first loads, populate the array by sorting the set. The only problem with this is that I would then have to separately maintain both the set and the array; modifying, inserting, or deleting objects from both anytime the user changes something. Is that considered the "correct" way to display CoreData elements in a table?
I would definitely go with option B. Even though you would be maintaining your model data, and the array in your controller, this should not be too difficult. adding / deleting items from the controller would require an update to the model. Not only do you get around your problem of risking data duplication, but you would see a big gain in performance as you aren't acquiring a newly sorted array each time you call for it.
Define "okay". It's likely not as efficient if you're sorting the same keys he same way every time. On the other hand, cycles are cheap; if you're not worried about performance and this is the clearest way, then go for it.
What you seem to be asking about "sorted the same way every time" is what's called a "stable sort". Ask yourself this: if the order of something other than the key(s) used, then why aren't you sorting by those too?