Singleton Design Implementation - objective-c

As per my previous question, here, I've adapted my Data Controller class over to use a singleton design pattern so that I can use it only once across multiple views. However I do have a couple question I can't seem to find the solution too.
Firstly I'm not exactly sure how to call the class/object in the two views to make it work, and secondly I've made the initialisation method global with + but do I need to do this with each of the methods?
The initialisation of of the class that I want to be able to share across the views, in order to share the data, is
static SpeecherDataController *_instance = nil; // <-- important
+(SpeecherDataController *)instance
{
// skip everything
if(_instance) return _instance;
// Singleton
#synchronized([SpeecherDataController class])
{
if(!_instance)
{
_instance = [[self alloc] init];
// NSLog(#"Creating global instance!"); <-- You should see this once only in your program
}
return _instance;
}
return nil;
}
The class uses three Mutable Arrays as the main content which need to be both set and read in the two views.

If I understand your questions correctly, I think the answers are:
You can use something like:
SpeecherDataController * localReference = [SpeecherDataController instance];
and then later:
[localReference someMessage:param]; // or ...
localReference.property = whatever;
No, the methods on your SpeecherDataController class do not also need to be made class methods (i.e., they do not need to have the + prefix, they can use - if you want to access ivars within them).
Note: I think you want to replace [[self alloc] init]; with [[SpeecherDataController alloc] init]; in your implementation of instance.
(Also, note: I was unable to follow your link to "here" above to see your previous question. So my apologies if I misunderstood something.)

Related

Objective C Convenience Method Use

I am tring to understand convenience methods.
IF I have a sqlite database containing store details and am returning these store details in a FMResultSet. I am thinking that to create an array of these store details as Store objects, that the best way would be create an object of type Store in one go in a convenience method and add to array.
The Class I have created is as below with convenience method
#interface StoreDetails : NSObject
#property (nonatomic, strong) NSString *storeName;
etc etc etc
+ (instancetype)storeWithStoreName:(NSString *)storeName
TelephoneNumber:(NSString *)
telephoneNumber: etc .......
My ResultSet loop would be as below?
NSMutableArray *Stores = [[NSMutableArray alloc] init];
while ([rs next]) {
Store *store =
[Store storeDetailsWithStoreName:[rs stringForColumn:#"storename"]
telephoneNumber:[rs stringForColumn:#"TelephoneNo"]];
[Stores addObject:store];
}
Is my thinking correct as above is is it better to go as below.
NSMutableArray *Stores = [[NSMutableArray alloc] init];
while ([rs next]) {
Store *store = [Store alloc] init];
store.storeName = [rs stringForColumn:#"storename"];
store.telephoneNumber = [rs stringForColumn:#"TelephoneNo"];
[Stores addObject:store];
}
All I am trying trying to understand is why you would use one over the other in noob speak, thankyou.
I think you have a good approach: initializing your Store object in a method of the Store class.
The storeDetailsWithStoreName:... method you have defined is a good example of what Apple calls a factory method (assuming you aren't doing anything weird in its implementation). It's a quite common pattern; Foundation has all sorts of examples: arrayWithCapacity:, numberWithInt:, etc.
With ARC, the simplest examples of these factory methods are nearly identical to a corresponding alloc/init expression, since the developer no longer has to think about autoreleasing objects. But there are still plenty of uses for factory methods, e.g. special instantiation patterns such as singleton or flyweight, including a small amount of common conversion or formatting code for convenience, implementing class clusters, etc. And there's the simple convenience of not having an extra set of brackets and less indentation.
The instancetype keyword is a good choice. This allows you to send the same message to a subclass of Store, with the expectation that the method will instantiate an object of the subclass using the same init method, like this:
+ (instancetype)storeWithStoreName:(NSString *)storeName
telephoneNumber:(NSString *)
...
{
return [[self alloc] initWithStoreName:...];
}
In the code above, as it's a class method, the self in [self alloc] is the Class object (either Store or a subclass of Store) rather than a specific instance of Store. This is what allows creating an instance of the correct class at runtime, depending on whether you call [Store storeWithStoreName:...] or [MoreSpecificStoreSubType storeWithStoreName:...].
The alternative to a factory method, or compliment to it really, is to declare a custom init method in your Store class:
- (id)initWithStoreName:(NSString *)storeName
telephoneNumber:(NSString *)telephoneNumber ...
…and use that directly inside your loop, instead of a factory method. Again, with ARC, not much of a difference between the two unless there's extra work you want to do in the factory method. You can have multiple variants of the init method; the standard practice is for all of them to call the most detailed init method, which is called the designated initializer.
I would recommend taking the time to read the Apple documentation pages on standards for class design (I linked to some of these pages above). Since there are a lot of this is based more on convention rather than language design restrictions, it's important to know all about the patterns and best practices for good design and proper behavior of special methods.

What should be done with inherited factory methods?

Suppose I have a class BasicDate, and a subclass of BasicDate called EuroDate. The difference between the classes is month-day-year versus day-month-year. I know it'd probably be better to just have methods on the same class to output them differently... but that's not the point of this question.
BasicDate has the following init method:
-(id)initWithMonth:(int)m andDay:(int)d andYear:(int)y {
if(self = [super init]) { /*initialize*/ } return self;
}
And the matching factory method then looks like this:
+(BasicDate)dateWithMonth:(int)m andDay:(int)d andYear:(int)y {
return [[BasicDate alloc] initWithMonth: m andDay: d andYear: y];
}
But if my subclass, EuroDate which would use a factory method more like this:
+(EuroDate)dateWithDay:(int)d andMonth:(int)m andYear:(int)y {
return [[EuroDate alloc] initWithDay: d andMonth: m andYear: y];
} //we can assume that EuroDate includes this init method...
This is all fine. Now, we assume that both classes have their own description method, which will print MMDDYYYY for BasicDate, but DDMMYYYY with EuroDate. This is still all fine.
But if I do this:
EuroDate today = [EuroDate dateWithMonth:10 andDay:18 andYear:2013];
This will call the BasicDate factory method that EuroDate has inherited. The problem is, remember how BasicDate's factory method looks? return [[BasicDate alloc] ...]
So today polymorphs into a BasicDate despite me wanting to store it as a EuroDate, so if I call the description method, it will print 10182013 rather than 18102013.
There are two solutions to this problem I have found.
Solution 1: Change BasicDate's factory method. Rather than return [[BasicDate alloc] ..., I can instead do return [[[self class] alloc] ...] This works and will allow me to use this method for BasicDate or any of BasicDate's subclasses and it will return the right object type.
Solution 2: Override the factory method. Whether I override it to throw an exception or override it to do return [[EuroDate alloc] ...]. The problem with overriding it is that I have to override every factory method for every subclass.
Which is better? What are some downsides to the two possible solutions that I may be missing? What is considered the standard way of handling this issue in Objective C?
You should generally use [[[self class] alloc] init...] in factory methods to ensure that they create instances of the correct class. Note that class isn't a property (and in fact, there's no such thing as a 'class property') so the use of dot syntax there is inappropriate.
Edit
And as pointed out by #ArkadiuszHolko (and Rob, thanks), you should now use instancetype rather than id for the return value, to get the benefits of strong typing while maintaining type flexibility for subclasses. And by the way, Apple's naming conventions suggest avoiding using the word 'and' in method names. So consider rewriting your convenience method like so:
+ (instancetype)dateWithMonth:(int)month day:(int)day year:(int)year
{
return [[self alloc] initWithMonth:month day:day year:year];
}

Thread-Safe lazy initialization in getter

I would like to know if both of the following solutions for lazy initialization are correct.
I have a class AppContext that is supposed to hold references to other class that should only exist once (Avoiding making every single one of these classes a singleton). Let's say one of these other classes is called ReferencedClass. That being said, I would like to lazy-initialize the references with defaults, in a thread-safe way.
It has been discussed before, and I have read a lot about it, but I am still unsure. Personal preferences aside, what I would like know is: Are these two solutions a correct way to implemented my desired behavior?
Solution 1: Originally I wanted to implement it like this:
// Getter with lazy initialized default value
- (ReferencedClass *)referencedClass {
// Check if nil. If yes, wait for lock and check again after locking.
if (_referencedClass == nil) {
#synchronized(self) {
if (_referencedClass == nil) {
// Prevent _referencedClass pointing to partially initialized objects
ReferencedClass *temp = [[ReferencedClass alloc] init];
_referencedClass = temp;
}
}
}
return _referencedClass;
}
// Setter
- (void)setReferencedClass:(ReferencedClass *)referencedClass {
#synchronized(self) {
_referencedClass = referencedClass;
}
}
Solution 2: Then I decided to go with GCD instead, so I wrote this:
// Getter with lazy initialized default value
- (ReferencedClass *)referencedClass {
// Check if nil. If yes, wait for "lock" and check again after "locking".
if (_referencedClass == nil) {
dispatch_sync(syncDispatchQueue, ^{
if (_referencedClass == nil) {
// Prevent _referencedClass pointing to partially initialized objects
ReferencedClass *temp = [[ReferencedClass alloc] init];
_referencedClass = temp;
}
});
}
return _referencedClass;
}
// Setter
- (void)setReferencedClass:(ReferencedClass *)referencedClass {
dispatch_sync(syncDispatchQueue, ^{
_referencedClass = referencedClass;
});
}
Of course, somewhere (for example in the init-Method) I have initialized the syncDispatchQueue with something like:
syncDispatchQueue = dispatch_queue_create("com.stackoverflow.lazy", NULL);
Is this correct, thread-safe and deadlock-free code? Can I use the double-checked-locking together with the temp-variable? If this double-checked-locking is not safe, would my code in both cases be safe if I removed the outer checks? I guess so, right?
Thanks very much in advance!
[Side note: I am aware of dispatch_once and that some people say that (in contrary to the Apple documentation) it can also be used with instance variables. For now I would like to use one of these two options though. If possible. ]
As far as I understand it, your "double-checked locking" mechanism is not thread-safe,
because the assigment _referencedClass = ... is not atomic. So one thread might read a partially initialized variable in the outer if (_referencedClass == nil) check.
If you remove the outer checks, both versions look OK to me.
You may be interested in
What advantage(s) does dispatch_sync have over #synchronized?
which has a great answer explaining the differences in implementation and performance.

Self destructing singleton design pattern iOS

I recently came across an issue in which I only wanted one instance of a particular object to exist, and exist for only the brief period of time it needed to perform a specific operation. Its operation was asynchronous so ARC would dealloc it at the end of the run loop if I didn't hold a reference to it. If I did hang onto it I would need delegate callbacks or notifications to know when it was done to release it.
The object needed to download several images and other data and cache it to disk. I didn't want it to waste memory when it wasn't caching items since the cache limit was around 24 hours. I also didn't need feedback of any kind from it; I wanted it to perform it's task and be done with itself.
I came up with a design pattern I liked quite nicely. I've used it in a few other projects since then, and was curios if it was a well known and analyzed pattern that I'm just not aware of (self-destructing singleton???). I'd like to know so I can be made aware of any potential pitfalls I'm not currently seeing.
I'm also very interested to hear any input you guys might have about why this is a bad design.
The Design Goes Like This (this is ARC, but non-arc can work too if you release the singleton through a class method):
A global static object (not really a singleton because it doesn't live the entire time)
static MySelfDestructingClass* singleton;
A single public class method
+ (void)downloadAndCacheDataIfNeeded
{
//Force synchronized access
#synchronized(singleton){
//We are already doing something, return
if(singleton){
return;
}
NSDate* lastCacheDate = [[NSUserDefaults standardDefaults] objectForKey:kKeyForLastUpdate];
if([[NSDate date] timeIntervalSinceDate:lastCacheDate] > kCacheLimit){
//Our cache is out of date, we need to update
singleton = [[self alloc] init];
[singleton downloadAndCache];
}
}
}
Now our instance methods, we need our object alive so the request can come back:
- (void)downloadAndCache
{
//This would probably be a delegate, but for simplicity of this example it's a notification
[[NSNotificationCenter defaultCenter] addObserver:self forNotificationWithName:NotificationSomeRequestDidSucceed selector:#selector(someCustomRequestDidSucceed:withData:) object:nil];
[SomeCustomRequest makeRequestWithURL:#"http://www.someURL.com"];
}
- (void)someCustomRequestDidSucceed:(SomeCustomRequest *)request withData:(NSDictionary *)dictionary
{
//Do whatever we need to in order to save our data, or fire off image download requests etc...
....
//Set our lastUpdated time in NSUserDefaults
[[NSUserDefaults standardDefaults] setObject:[NSDate date] forKey:kKeyForLastUpdate];
//Remove our observer
[NSNotificationCenter defaultCenter] removeObserver:self name:NotificationSomeRequestDidSucceed object:nil];
//Release ourselves (ok not really, but tell arc we can be released)
singleton = nil;
}
This way all I have to do anywhere else in the application is:
[MySelfDestructingClass downloadAndCacheDataIfNeeded];
Now this object will download things if it needs to and release itself when it's done, or not create itself at all. It also won't go and start downloading the data twice.
I'm aware this design has limitations with extendibility and functionality, but for an instance like this, and the other ones I've used it for, I've found it quite useful.
This pretty common using blocks. Consider something similar (though I would probably handle multiple invocations differently...)
void ExecuteWithMySingleSelfDestructingObject(void(^block)(MySelfDestructingClass *object)) {
static MySelfDestructingClass* singleton;
#synchronized(singleton) {
if (singleton) {
// To get past the synchronization primitive, this must be a recursive call.
}
// Whatever other conditions you want to have (like your date check)
singleton = [[MySelfDestructingClass] alloc] init];
#try { block(singleton); }
#finally { singleton = nil; }
}
}
Note double exception handling (try/finally plus what #synchronized does - may want to change that...
Then do whatever you want with the block...
ExecuteWithMySingleSelfDestructingObject(^(MySelfDestructingClass *object){
// Do whatever I want with the singleton instance that has
// been given to me as <object>
});
Of course, it could be a class method...
+ (void)performBlock:(void(^)(MySelfDestructingClass *object))block {
static MySelfDestructingClass* singleton;
#synchronized(singleton) {
if (singleton) {
// To get past the synchronization primitive, this must be a recursive call.
}
// Whatever other conditions you want to have (like your date check)
singleton = [[self] alloc] init];
#try { block(singleton); }
#finally { singleton = nil; }
}
}
[MySelfDestructingClass performBlock:^(MySelfDestructingClass *object){
// Do whatever I want with the singleton instance that has
// been given to me as <object>
}];
I hope that makes sense (I typed it free-hand, so syntax may vary, but you should get the idea).

Singleton Design

I'm creating a game that uses cards.
I have an AppController class with one instance in the nib.
The AppController instance has an NSArray instance variable called wordList.
On init, the nib's instance of AppController generates a new GameCard.
Every gamecard has an array of words containing 5 words selected at random from the the list in AppController.
Because the list is large, I'd like to read it into memory only once. Therefore, I want only one instance of AppController, as a singleton class. Every time a new GameCard is created from within AppController, it should access that same singleton instance to retrieve the wordlist.
So basically, I need a singleton AppController that creates GameCards, where each GameCard has a reference to the original AppController.
I'm not sure how to implement this. Sorry if the explanation was confusing.
A code example I found online follows (http://numbergrinder.com/node/29)
+ (AppController *)instance
{
static AppController *instance;
#synchronized(self) {
if(!instance) {
instance = [[AppController alloc] init];
}
}
return instance;
}
But when I tried to do something with it in a GameCard instance through the code below, my application took forever to launch and Xcode told me it was loading 99797 stack frames.
AppController *controller = [AppController instance];
It sounds like an infinite loop. Make sure that -[AppController init] isn't calling +[AppController instance].
Why does every card need a reference to the app controller?
If it's just to access its words, it's simpler to let each card own its words directly. Make a new method named initWithWords: the designated initializer for the GameCard class. Initialize each card with the array of its five words, and have the card own that array for its lifetime.
Removing the cards' references to the app controller would resolve the infinite loop that Tom astutely detected.
Also, if no word should appear on two cards at once, remember to take that into account when drawing from the app controller's Great Big Array Of Words, and when destroying cards (you may or may not want the words to go back into the pile for future cards).
It sounds like you're on the right track. I've never tried to put a reference to a singleton in a nib file, though. You may want to create a separate singleton class that maintains a copy of the data (DataManager, maybe?), and then call it from within your instance of AppController to fetch the words.
You may find that putting a singleton within a nib (using the code for a singleton in Stu's post) works just fine, though. Good luck!
It looks like you may be calling your class instance method from within your init method. Try something like this:
static AppController* _instance = nil;
- (id)init
{
// depending on your requirements, this may need locking
if( _instance ) {
[self release];
return _instance;
}
if( (self = [super init]) ) {
_instance = [self retain];
// do your initialization
}
return self;
}
+ (AppController*)instance
{
if( _instance ) return _instance;
else return [[AppController alloc] init];
}
This makes sure that only one instance of AppController is ever available and also that it's safe to allocate it as well as getting a copy through the instance class method. It's not thread safe, so if it's going to be accessed by multiple threads, you should add some locking around the checks to _instance.
The normal way to create an AppController/AppDelegate is to add a custom NSObject to your MainMenu/MainWindow.xib file. Set the class to be AppController. Link your UIApplication/NSApplication delegate reference to your AppController object. Then you can get your single AppController with either
(AppController*)[NSApp delegate];
or
(AppController*)[[UIApplication sharedApplication] delegate];
You never have to create it with alloc/init because it will be created when your application is launched. You don't have to worry about making it a singleton because no one will ever try to create another one. And you don't have to worry about how to access it because it will be the delegate of the UIApplication/NSApplication object.
All that said, if you need a global variable holding an array of words, then forget about the AppController and make a new singleton object which holds/reads the array. In which case you just need:
+ (NSArray *)sharedWordListArray
{
static NSArray *wordList;
if( !wordList ) {
wordList = [[NSMutableArray alloc] init];
// read array
}
return wordList;
}
If you really need thread safety, then simply call [WordList sharedWordListArray] from your app delegate's applicationDidFinishLaunching: method before starting any threads, or add an NSLock if you really want to defer the loading to later, but often its better to take the load time hit at the start of the program rather than unexpectedly when the user takes some later action.