1

I asked a question yesterday regarding my table view and linking unique detail views to each cell in the table view. I believe I got a good answer to my question here. (Hopefully you can read that post and see what I need). Basically I wanted to know if I am making my singleton correctly. Here is my code:

timerStore.h

#import "Tasks.h"
@interface timerStore : NSObject
{
    NSMutableDictionary *allItems;
}
+(timerStore *)sharedStore;
-(NSDictionary *)allItems;
-(NSTimer *)createTimerFor:(Tasks *)t inLocation: (NSIndexPath *)indexPath;
-(void)timerAction;
@end

timerStore.m

@implementation timerStore

+(timerStore *)sharedStore{
    static timerStore *sharedStore = nil;
    if (!sharedStore)
        sharedStore = [[super allocWithZone:nil]init];
    return sharedStore;
}
+(id)allocWithZone:(NSZone *)zone{
    return [self sharedStore];
}
-(id)init {
    self = [super init];
    if (self) {
        allItems = [[NSMutableDictionary alloc]init];
    }
    return self;
}
-(NSDictionary *)allItems{
    return allItems;
}
-(NSTimer *)createTimerFor:(Tasks *)t inLocation: (NSIndexPath *)indexPath {
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:t.timeInterval target:self selector:@selector(timerAction) userInfo:nil repeats:1.0];
    [allItems setObject:timer forKey:indexPath];
    return timer;
}
-(void)timerAction{
//custom properties here
}
@end

I'm kind of confused because I was under the impression that a cell's index path gets recycled as you scroll down (dequeue). I may be wrong though. Anyway, am I on the right path to making a singleton as the guy in the link suggested?

Community
  • 1
  • 1
EvilAegis
  • 733
  • 1
  • 9
  • 18
  • You know, I've been programming iOS for 4 years now -- worked on a half-dozen different large apps. I've yet to need to use a singleton. – Hot Licks Jul 29 '13 at 03:44
  • 1
    In particular, if you have a table view you must have a view controller for it. That view controller can contain the data for the table (functioning as a delegate). There is no need for a singleton to store table data. – Hot Licks Jul 29 '13 at 03:47
  • yea i wanted to avoid using singletons but i didn't know how else to do this. basically im using the NSFetchedResultsController to populate the table view (linked to UIViewController subclass). Each cell should have a timer in its detail view (which results from didSelectRowAtIndexPath). Apparently a singleton is the best way to make sure multiple timers can co-exist and reduce memory usage by limiting the detail view to one intialization...more info is at the link in the OP – EvilAegis Jul 29 '13 at 04:05
  • 4
    Not related to question but "Never ever start class names with lower case !!!" – Janak Nirmal Jul 29 '13 at 04:23
  • 1
    It's not clear to me that using a singleton is the way to go. Even though the answer I gave to your other question involves creating a new detail view controller for each row selected, that's not necessarily a bad thing. When profiling that app with instruments, selecting nine rows only added 1.8 kb of memory -- view controllers are not that heavy an object (but that might depend on what you have in them, especially images). How many tasks do you think a user would be creating? A few? Tens? Hundreds? – rdelmar Jul 29 '13 at 05:30
  • Honestly probably 20 at most – EvilAegis Jul 29 '13 at 05:40
  • By the way, like I said before, I was under the impression that a cell's index path gets recycled as you scroll down (dequeue). Doesn't that mean marking each cell with a number identifier would result in multiple cells for the same identifier? – EvilAegis Jul 29 '13 at 06:28
  • Also, if you stored each view controller with a indexPath key, how do you make sure the key isn't set to two view controllers..? For example. Let's say you have 4 cells, which means 4 view controllers. You delete cell 3. Cell 4 moves down to cell 3s spot. You create a new cell which goes to spot 4. Now you have two controllers with the same indexPath key! How do you avoid this?? – EvilAegis Jul 29 '13 at 16:43
  • You maintain an NSMutableArray that "shadows" the contents of the table. – Hot Licks Jul 30 '13 at 10:51
  • You keep saying "the cell's index path gets recycled". The index path doesn't get recycled; the cell is what gets recycled. – Abizern Aug 15 '13 at 09:08

1 Answers1

2

The best way to implement App Singleton is as follows

Header file

#import <Foundation/Foundation.h>

@interface AppSingleton : NSObject

@property (nonatomic, retain) NSString *username;

+ (AppSingleton *)sharedInstance;

@end

Implementation File

#import "AppSingleton.h"

@implementation AppSingleton
@synthesize username;

+ (AppSingleton *)sharedInstance {
    static AppSingleton *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

// Initializing
- (id)init {
    if (self = [super init]) {
        username = [[NSString alloc] init];
    }
    return self;
}

@end

Note: What this does is it defines a static variable (but only global to this translation unit) called sharedInstance which is then initialised once and only once in sharedInstance Method. The way we ensure that it’s only created once is by using the dispatch_once method from Grand Central Dispatch (GCD). This is thread safe and handled entirely by the OS for you so that you don’t have to worry about it at all.

Using Singleton To set value

[[AppSingleton sharedInstance] setUsername:@"codebuster"];

Using Singleton to get value.

NSString *username = [[AppSingleton sharedInstance] username];

Further Reference and Reading

James Kuang
  • 10,710
  • 4
  • 28
  • 38
icodebuster
  • 8,890
  • 7
  • 62
  • 65
  • Why don't you refer the OP to [this page](http://www.galloway.me.uk/tutorials/singleton-classes/) instead? By the way did you *read* the question at all? – Khanh Nguyen Jul 29 '13 at 04:44
  • 1
    @KhanhNguyen I used to refer to links but mostly get downvoted for that. :) – icodebuster Jul 29 '13 at 04:45
  • thanks for telling me how to make a singleton, but i was more interested if i was on the right track in the context of what the guy in the link (in original post) suggested – EvilAegis Jul 29 '13 at 05:09
  • I think it can not prevent user to use `[[AppSingleton alloc] init]` get another instance in ARC. And I have a look at your link , in NON-ARC , it can prevent user to use `[[AppSingleton alloc] init]` get another instance. – Guo Luchuan Jul 29 '13 at 06:10
  • 2
    @KhanhNguyen It is better to have an answer **written** than a link to some other place – Lithu T.V Jul 29 '13 at 06:20
  • @KhanhNguyen: Or this one: http://stackoverflow.com/questions/7568935/how-do-i-implement-an-objective-c-singleton-that-is-compatible-with-arc/7569010#7569010 or this one: http://stackoverflow.com/questions/9119042/why-does-apple-recommend-to-use-dispatch-once-for-implementing-the-singleton-pat/9119089#9119089 or this one: http://stackoverflow.com/questions/5720029/create-singleton-using-gcds-dispatch-once-in-objective-c or.... Just do a search here on SO and mark this as a duplicate if that's all that you want to add... – lnafziger Jul 29 '13 at 14:27
  • My question has not been answered... i was more interested if i was on the right track in the context of what the guy in the link (in original post) suggested – EvilAegis Jul 29 '13 at 16:34