What technical reasons are there not to make a singleton class to manage my Core Data? I'm trying to make a decision now, if I should strip out all of the boilerplate core data code and re-implement it in a singleton.
The boilerplate code in the application delegate in the Xcode templates is functionally implemented as a singleton. The application object is a singleton and it maintains but one delegate object so you've only got one instances of the Core Data stack and since the application object is universally accessible, you can always get to the app delegate as well.
However, even that works only for simple apps with one persistent store with all the context using that one store. In more complex apps you may have multiple stores or context so a singleton quickly becomes too bloated.
A singleton usually won't buy you much complexity hiding or save duplicate coding because most of the coding you have to do with Core Data is in the controller layer where you link up the model to the view/interface. Since that logic is usually custom to each view, you can't actually park it in the singleton.
I've used singletons in the past but in the end they usually prove more hassle than they are worth.
There are two important considerations (note these are not the only two) when deciding if a singleton is right for you:
Threading
Memory Usage
Threading
Singletons are convenient, but if your application uses multiple threads you might be tempted to write something like this:
[[CDSingleton managedObjectContext] executeFetchRequest:someFetch];
//later on a background thread you might write
NSManagedObject *object = [[CDSingleton managedObjectContext] objectWithID:objectID];
Shortly after that, your application will crash because you've accessed a managedObjectContext which was likely created on the main thread from some other thread.
Memory Usage
Singletons never go away, that's the point of a Singleton. Thus, they also never willingly free their consumed resources. In the case of CoreData that means the managed object context will continue to hold managed objects in memory until you call -reset or -save:.
That could be bad if your app uses a lot of data.
Best practice is to pass the managed object context between view controllers. Apple documentation and samples do that. You should never really have to access your app delegate, not for Core Data, not for anything.
http://www.cimgf.com/2011/01/07/passing-around-a-nsmanagedobjectcontext-on-the-iphone/
Related
While recently working with Objective-C and various libraries written in it, I've noticed two really popular singleton patterns. One version fetches the singleton instance and calls its instance methods and other version only exposes class methods and never gives you an instance to work with. All have the purpose of abstracting access to a single resource (StoreKit, CoreData, Parse API etc.). For example, here's the former approach used in MKStoreKit:
// initialize singleton during app boot
[MKStoreManager sharedManager]
// sometime later in the app
[[MKStoreManager sharedManager] buyFeature:kFeatureAId
onComplete:^(NSString* purchasedFeature)
{
NSLog(#"Purchased: %#", purchasedFeature);
}
onCancelled:^
{
NSLog(#"User Cancelled Transaction");
}];
or alternatively NSUserDefaults, UIApplication etc.. The other approach can be seen in MagicalRecord or here with Parse API:
// configure API credentials sometime during app boot
[Parse setApplicationId:#"123456"
clientKey:#"123456"];
// sometime later
PFObject *testObject = [PFObject objectWithClassName:#"TestObject"];
[testObject setObject:#"bar" forKey:#"foo"];
[testObject save];
What are some pros and cons of the two approaches and is one of them fundamentally better than the other?
Not having to retrieve the shared instance saves some screen estate (the performance difference is likely irrelevant), but am I screwing myself in some other way, for example, testability-wise?
Thanks!
There are two different ways to implement the approach based on class methods:
Make a singleton instance using a class hidden from everybody, and hide its methods behind wrapper class methods with identical signatures, or
Make class methods that do all the work
The implications of the first implementation are that everything you can do with a singleton, you can do with the hidden singleton:
using a subclass becomes a possibility
switching the instance in the middle of the run is easy
the state lives in instance variables
initialization follows the familiar pattern
If you go for an implementation that does not use a singleton, you would be relying on static variables to keep your current state. That is a legitimate choice, but the initialization pattern becomes different (perhaps even using a dispatch_once), you cannot switch the implementation in the middle without relying on some ugly if conditions, and using a subclass becomes a lot more tricky.
Testing the first implementation is somewhat easier than testing the second one, because you can provide a separate implementation of the singleton for testing, perhaps through the back door; with a static-based implementation, this route cannot be taken.
To summarize, I would use a singleton-based solution, with the singleton optionally hidden behind a "facade" that provides access to singleton's methods. I would not use an implementation where all state must be placed in static variables.
One advantage of the singleton approach is that it becomes trivial to allow other instances if you need to. If you take the class method approach, that's all you get without a lot of refactoring.
I'm creating my managed object context with NSPrivateQueueConcurrencyType concurrency type.
Also I'm using performBlock: selector to execute operations in background. So If I'm fetching some objects in background (in performBlock:), is it safe to use resulting managed objects in main thread?
As a general rule, no it is not safe to share NSManagedObject instances across threads no matter what concurrency type you are using.
However there is a library you can use to make your context(s) and object instances thread-safe. With that you can pretty much ignore all the nonsense about ensuring thread isolation between contexts and focus your efforts on the things that matter, like building out the actual functionality of your app.
I'm not 100% sure, but in my own experience I do it this way: If you are changing the variables properties, do it inside performBlock. I had one case where reading was causing some weird behavior, but in general it seems to be OK. If you want to be extra safe, use performBlock every time you touch a managed object in any way.
You will need to use a different context for each thread as explained here iOS Developer - Core data multithreading
One way to implement is described at Core Data - one context per thread implementation
Sorry, I should've search better, here is exactly my question & answer to it:
Core Data's NSPrivateQueueConcurrencyType and sharing objects between threads
Question
We're developing a custom EventEmitter inspired message system in Objective-C. For listeners to provide callbacks, should we require blocks or selectors and why?
Which would you rather use, as a developer consuming a third party library? Which seems most in line with Apple's trajectory, guidelines and practices?
Background
We're developing a brand new iOS SDK in Objective-C which other third parties will use to embed functionality into their app. A big part of our SDK will require the communication of events to listeners.
There are five patterns I know of for doing callbacks in Objective-C, three of which don't fit:
NSNotificationCenter - can't use because it doesn't guarantee the order observers will be notified and because there's no way for observers to prevent other observers from receiving the event (like stopPropagation() would in JavaScript).
Key-Value Observing - doesn't seem like a good architectural fit since what we really have is message passing, not always "state" bound.
Delegates and Data Sources - in our case, there usually will be many listeners, not a single one which could rightly be called the delegate.
And two of which that are contenders:
Selectors - under this model, callers provide a selector and a target which are collectively invoked to handle an event.
Blocks - introduced in iOS 4, blocks allow functionality to be passed around without being bound to an object like the observer/selector pattern.
This may seem like an esoteric opinion question, but I feel there is an objective "right" answer that I am simply too inexperienced in Objective-C to determine. If there's a better StackExchange site for this question, please help me by moving it there.
UPDATE #1 — April 2013
We chose blocks as the means of specifying callbacks for our event handlers. We're largely happy with this choice and don't plan to remove block-based listener support. It did have two notable drawbacks: memory management and design impedance.
Memory Management
Blocks are most easily used on the stack. Creating long-lived blocks by copying them onto the heap introduces interesting memory management issues.
Blocks which make calls to methods on the containing object implicitly boost self's reference count. Suppose you have a setter for the name property of your class, if you call name = #"foo" inside a block, the compiler treats this as [self setName:#"foo"] and retains self so that it won't be deallocated while the block is still around.
Implementing an EventEmitter means having long-lived blocks. To prevent the implicit retain, the user of the emitter needs to create a __block reference to self outside of the block, ex:
__block *YourClass this = self;
[emitter on:#"eventName" callBlock:...
[this setName:#"foo"];...
}];
The only problem with this approach is that this may be deallocated before the handler is invoked. So users must unregister their listeners when being deallocated.
Design Impedance
Experienced Objective-C developers expect to interact with libraries using familiar patterns. Delegates are a tremendously familiar pattern, and so canonical developers expect to use it.
Fortunately, the delegate pattern and block-based listeners are not mutually exclusive. Although our emitter must be able to be handle listeners from many places (having a single delegate won't work) we could still expose an interface which would allow developers to interact with the emitter as though their class was the delegate.
We haven't implemented this yet, but we probably will based on requests from users.
UPDATE #2 — October 2013
I'm no longer working on the project that spawned this question, having quite happily returned to my native land of JavaScript.
The smart developers who took over this project decided correctly to retire our custom block-based EventEmitter entirely.
The upcoming release has switched to ReactiveCocoa.
This gives them a higher level signaling pattern than our EventEmitter library previously afforded, and allows them to encapsulate state inside of signal handlers better than our block-based event handlers or class-level methods did.
Personally, I hate using delegates. Because of how objective-C is structured, It really clutters code up If I have to create a separate object / add a protocol just to be notified of one of your events, and I have to implement 5/6. For this reason, I prefer blocks.
While they (blocks) do have their disadvantages (e.x. memory management can be tricky). They are easily extendable, simple to implement, and just make sense in most situations.
While apple's design structures may use the sender-delegate method, this is only for backwards compatibility. More recent Apple APIs have been using blocks (e.x. CoreData), because they are the future of objective-c. While they can clutter code when used overboard, it also allows for simpler 'anonymous delegates', which is not possible in objective C.
In the end though, it really boils down to this:
Are you willing to abandon some older, more dated platforms in exchange for using blocks vs. a delegate? One major advantage of a delegate is that it is guaranteed to work in any version of the objc-runtime, whereas blocks are a more recent addition to the language.
As far as NSNotificationCenter/KVO is concerned, they are both useful, and have their purposes, but as a delegate, they are not intended to be used. Neither can send a result back to the sender, and for some situations, that is vital (-webView:shouldLoadRequest: for example).
I think the right thing to do is to implement both, use it as a client, and see what feels most natural. There are advantages to both approaches, and it really depends on the context and how you expect the SDK to be used.
The primary advantage of selectors is simple memory management--as long as the client registers and unregisters correctly, it doesn't need to worry about memory leaks. With blocks, memory management can get complex, depending on what the client does inside the block. It's also easier to unit test the callback method. Blocks can certainly be written to be testable, but it's not common practice from what I've seen.
The primary advantage of blocks is flexibility--the client can easily reference local variables without making them ivars.
So I think it just depends on the use case--there is no "objective right answer" to such a general design question.
Great writeup!
Coming from writing lots of JavaScript, event-driven programming feels way cleaner than having delegates back and forth, in my personal opinion.
Regarding the memory-managing aspect of listeners, my attempt at solving this (drawing heavily from Mike Ash's MAKVONotificationCenter), swizzles both the caller and emitter's dealloc implementation (as seen here) in order to safely remove listeners in both ways.
I'm not entirely sure how safe this approach is, but the idea is to try it 'til it breaks.
A thing about a library is, that you can only to some extend anticipate, how it will be used. so you need to provide a solution, that is as simple and open as possible — and familiar to the users.
For me all this fits best to delegation. Although you are right, that it can only have on listener (delegate), this means no limitation, as the user can write a class as delegate, that knows about all desired listeners and informs them. Of course you can provide a registering class. that will call the delegate methods on all registered objects.
Blocks are as good.
what you name selectors is called target/action and simple yet powerful.
KVO seems to be a not optimal solution for me as-well, as it would possibly weaken encapsulation, or lead to a wrog mental model of how using your library's classes.
NSNotifications are nice to inform about certain events, but the users should not be forced to use them, as they are quite informal. and your classes wont be able to know, if there is someone tuned-in.
some useful thoughts on API-Design: http://mattgemmell.com/2012/05/24/api-design/
I have only one database model schema in my app, so IMHO, NSManagedObjectModel and NSPersistentStoreCoordinator objects might reside in main app delegate class for accessing from other parts of the app. However, I would like to have different NSManagedObjectContexts objects for various parts of my app because I will use multithreading.
From my personal database experience, I assume NSManagedObjectContext is somehow similar to the concept of database transaction. So, it's logical to have separate context objects for various multi-threaded parts of my app in order to avoid committing unwanted changes from one app part to another. When creating new project with enabled for core data, Xcode creates three essential methods in main app delegate
- (NSManagedObjectModel *)managedObjectModel{
// reads your database model file and defined entities from defined DataSchema.xcdatamodeld file
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
// uses already read database model and initializes defined sqlite database file and returns a persistent store coordinator - a pointer to the database
}
- (NSManagedObjectContext *)managedObjectContext{
// opens a connection (and transaction) to the database.
}
So, the question would be, is it reasonable to leave persistentStoreCoordinator and managedObjectModel methods in main app delegate (and access them through the app), but to move managedObjectContext method to those classes that need private data handling?
You're always going to have one main managed object context that runs on the main thread.
If you're doing background processing on another thread, you can create another NSManagedObjectContext on a background thread, pointing at the same NSPersistentStoreCoordinator.
When you save/delete/update in the background context, notifications are fired that you listen to on the main thread, and merge the changes back into the main context.
Personally, I don't have any Core Data objects in the App Delegate, because I don't think they belong there. I think Apple use that in their examples for simplicity of the example. I usually have a CoreDataStack object that is passed around where I need it.
You could look at a higher level Core Data API, such as Magical Record. I've just started using this and it's pretty useful, and removes a lot of the boilerplate code you get from Core Data. It's written by Marcus Zarra and team, a guy who apparently knows a lot about Core Data.
In iOS 5, Core data was improved by allowing ManagedObjectContexts to have a parent context. So in your case, your background contexts would be children to the parent context, and apparently it's a lot easier to merge back in. I haven't tried this yet though.
So, it's logical to have separate context objects for various
multi-threaded parts of my app in order to avoid committing unwanted
changes from one app part to another.
It is possible to have multiple contexts, which is a practice used widely.
is it reasonable to leave persistentStoreCoordinator and
managedObjectModel methods in main app delegate (and access them
through the app), but to move managedObjectContext method to those
classes that need private data handling?
You can leave it in the app delegate, accessing it via [[UIApplication sharedApplication] delegate].
You could create a separate singleton class containing the core data stack.
You could just pass a pointer to the managedObjectContext between classes.
Each viewController could create it's own context linking it to a parent context via setParentContext:.
As you can see it really depends on the complexity of your project. Generally if you have to a lot of specific retrievals and saves you might want to stick the Core Data stack in it's own class. For smaller projects why not just leave it in the app delegate and pass the context via a pointer.
Also, check out the 2011 WWDC session about Core Data. It talks about a bunch of cool new features.
I'm new to Mac programming and I'm working on a document-based application.
My NSDocument subclass creates a NSWindowController subclass. This window controller creates two NSViewController subclasses as well.
Sometimes, a change in one of the views of a NSViewController needs to notify the NSDocument and/or the main model class. Also, a change in the model needs to be notified to every/some view(s).
My question is: what is the best approach so that there is no (or minimum) coupling? I know there are several choices, but I'm not sure which one suits best for my application as I'm newbie not to programming but to Cocoa and especially NSDocument:
KVO. Looks nice and easy to implement, but I don't like the idea of not explicitly notifying the observer(s) about a change (AFAIK, self.someProperty = newValue does automagically notify observers), and don't like the fact that you have to register to property names which could change in time.
Notifications. I know what they are and I've used them for iOS. But I've read somewhere that they are not guaranteed to be sent immediately to observers. Is it true? If not, do you see them as a good approach for a document-based app?
Delegates. Yes, under normal conditions (or what I've usually seen), a class has one delegate. But creating an array of delegates works as well (just tested it). The problem I see here is that every time I need to notify the delegates I have to loop through them, make sure they respond to a method, and call that method.
Are there any other alternatives I'm missing?
KVO by a controller class is the most common way to do coupling between a model and its view(s). In fact, Cocoa Bindings, which are intended to mostly eliminate code in the controller layer, are based on KVO. It is true that KVO/KVC relies on property names, and that if those change, you'll have to change the bindings or KVO setup connecting your view. However, it's not usually feasible to make your views completely unaware of the underlying model specifics, so I don't see this as a problem.
My recommendation would be to use Cocoa Binding where you can, as they eliminate a lot of glue code. In places where they can't be used, your controllers (the middle layer in MVC) should use KVO to observe model changes and update the appropriate views. Changes in the views can be passed back to the model via property accessors and/or KVC by the controllers.
Yes, under normal conditions (or what I've usually seen), a class has
one delegate. But creating an array of delegates works as well (just
tested it).
Delegates are often used to modify the behavior of the delegating object. An application delegate is a good example: NSApplication by itself isn't very interesting; it relies on its delegate to define the interesting behavior of the application. Having multiple delegates all trying to modify the behavior of a single object could be a problem if the various delegates conflict with each other. What do you do if the delegates disagree?
There are some cases in Cocoa where a class uses more than one delegate, but each one has a separate role. For example, NSTableView has both a delegate and a data source, but both are really delegates of a sort.
The problem I see here is that every time I need to notify the
delegates I have to loop through them, make sure they respond to a
method, and call that method.
That's not hard to solve. For example, you could create an NSInvocation to encapsulate the call, and then send the invocation to each "delegate." However, if you do that you'll have nearly reinvented the notification system. If you need the one-to-many communication that you'd get with your multiple delegates proposal, you'll probably be better off using notifications or KVO.