Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a reason the managedObjectModel is re-created for each BSManagedDocument instance? #33

Open
Motti-Shneor opened this issue Nov 29, 2014 · 6 comments

Comments

@Motti-Shneor
Copy link

An NSManagedObjectModel is not very "lightweight" and it also is exactly the same for all the instances of a BSManagedDocument (or per specific subclass).

Question is: why not share the model for all open documents? If my app regularly keeps 5-6 documents open, and my model is pretty big (some 20 entities with many validation rules, relations etc) wouldn't it be wiser to have just one model ?

Or is it somehow cached behind the scenes by CoreData itself, when you [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]] every time?

@mikeabdullah
Copy link
Collaborator

I've followed Apple's lead an made this an instance method. On that basis, I was a bit wary of doing any extra caching beyond whatever Apple might be doing behind the scenes. I don't know if Apple have a particularly good reason for this setup, but they certainly seem keen on it, having used it again for UIManagedDocument, rather than going with a class method.

I suppose theoretically an app could be modifying the model before it's used for the first time, and that modification is per-document, but that does seem pretty unlikely!

All that said, are you actually finding this to be slow, or just speculating?

It's nice and easy in your app to override -managedObjectModel with your own cached implementation. We actually do this in Sandvox, partly because the caching is nice, but mostly because we want to load up a specific model, not the merged one.

@Motti-Shneor
Copy link
Author

I just like efficiency, and low memory footprint in any NS or UI App I’m doing.

I was expecting an “Infrastructure” class like BSManagedDocument to try to be efficient. If you tell me that NSManagedDocument and UIManagedDocument keep distinct models for each document - I’ll agree that this is the way to go in a replacement class like BSManagedDocument.

However, my question still stands: Could multiple CoreData stacks (for multiple open documents) share the same instance of the model for setup? Won’t Core-Data get angry?

On 30 בנוב׳ 2014, at 20:35, Mike Abdullah <[email protected] mailto:[email protected]> wrote:

I've followed Apple's lead an made this an instance method. On that basis, I was a bit wary of doing any extra caching beyond whatever Apple might be doing behind the scenes. I don't know if Apple have a particularly good reason for this setup, but they certainly seem keen on it, having used it again for UIManagedDocument, rather than going with a class method.

I suppose theoretically an app could be modifying the model before it's used for the first time, and that modification is per-document, but that does seem pretty unlikely!

All that said, are you actually finding this to be slow, or just speculating?

It's nice and easy in your app to override -managedObjectModel with your own cached implementation. We actually do this in Sandvox, partly because the caching is nice, but mostly because we want to load up a specific model, not the merged one.


Reply to this email directly or view it on GitHub #33 (comment).

@mikeabdullah
Copy link
Collaborator

I was expecting an “Infrastructure” class like BSManagedDocument to try to be efficient. If you tell me that NSManagedDocument and UIManagedDocument keep distinct models for each document - I’ll agree that this is the way to go in a replacement class like BSManagedDocument.

Well you haven't proven that we're being inefficient here. Counter-deal: you show me that UIManagedDocument and NSPersistentDocument are caching the model and I'll do the same.

If one were to be pedantic, caching the model isn't necessarily a magical efficiency win:

  • An app which only ever has one document open at a time (or tends to) still has the same memory footprint
  • If all documents get closed — or all documents of a particular type — the app is now losing out since more memory is being occupied than is actually needed

However, my question still stands: Could multiple CoreData stacks (for multiple open documents) share the same instance of the model for setup? Won’t Core-Data get angry?

My answer still stands:

It's nice and easy in your app to override -managedObjectModel with your own cached implementation. We actually do this in Sandvox, partly because the caching is nice, but mostly because we want to load up a specific model, not the merged one.

@adib
Copy link
Contributor

adib commented Dec 4, 2014

If all documents get closed — or all documents of a particular type — the app is now losing out since more memory is being occupied than is actually needed
This one case is solvable by using a weak hash map – thus if all documents are closed then the reference count to the model goes down to zero and the model gets deallocated.

However keep in mind that all of this is premature optimization – how big your models are anyway and on top of that the Mac has a page file (unlike iOS) hence it may not worth the extra effort and complexity to cache this.

However, my question still stands: Could multiple CoreData stacks (for multiple open documents) share the same instance of the model for setup? Won’t Core-Data get angry?

Sandvox seems to be doing this just fine, isn't it Mike?

@mikeabdullah
Copy link
Collaborator

Yes, it works just fine to share the same instance of the model

@Motti-Shneor
Copy link
Author

Well, the first to say "cache" was you... I never meant "caching" the model, but rather making it a "class property". First document will create the model, every document will retain it, the last document to be released, will release the model --- a simple old-style shared object.

Then, it is quite simple to see what NSDocument does. Just create 2 documents, and in the debugger crawl up the model stack until you see the addresses of the models of those documents. Are they the same object? Same method to see if UIManagedDocument does this too.

I'll test and tell you my results as soon as I can.

On 3 בדצמ 2014, at 19:12, Mike Abdullah [email protected] wrote:

I was expecting an “Infrastructure” class like BSManagedDocument to try to be efficient. If you tell me that NSManagedDocument and UIManagedDocument keep distinct models for each document - I’ll agree that this is the way to go in a replacement class like BSManagedDocument.

Well you haven't proven that we're being inefficient here. Counter-deal: you show me that UIManagedDocument and NSPersistentDocument are caching the model and I'll do the same.

If one were to be pedantic, caching the model isn't necessarily a magical efficiency win:

An app which only ever has one document open at a time (or tends to) still has the same memory footprint
If all documents get closed — or all documents of a particular type — the app is now losing out since more memory is being occupied than is actually needed
However, my question still stands: Could multiple CoreData stacks (for multiple open documents) share the same instance of the model for setup? Won’t Core-Data get angry?

My answer still stands:

It's nice and easy in your app to override -managedObjectModel with your own cached implementation. We actually do this in Sandvox, partly because the caching is nice, but mostly because we want to load up a specific model, not the merged one.


Reply to this email directly or view it on GitHub.

Motti Shneor
e-mail: [email protected]
phone: +972-8-9267730

mobile: +972-54-3136621

Ceterum censeo Microsoftinem delendam esse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants