Question

I have an issue, described below and solution. But I think our solution is not really "right way" to solve this issue.

1: I have thread safe singleton for Data

//DataSingleton.h
@interface DataSingleton : NSObject
@property (nonatomic, readonly, retain) NSString *userLogin;
-(void)setPrettyLogin:(NSString*)prettyLogin;
@end

and

//DataSingleton.m
#import "DataSingleton.h"

@synthesize userLogin   = _userLogin;

+(id)sharedSingleton{

    static dispatch_once_t DataSPred;
    static DataSingleton *shared = nil;
    dispatch_once(&DataSPred, ^{ shared = [[self alloc] init]; });
    return shared;
}

-(void)setPrettyLogin:(NSString*)prettyLogin{
    _userLogin = prettyLogin;
}

@end

2: Also I have same singleton for Network and i use feature

[NSURLConnection sendAsynchronousRequest:request 
     queue:[NSOperationQueue mainQueue] 
     completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) 
         { <block> }];
// I know about mainQueue - only for UI. Here it is, for clarity.

3: The issue

When i try get [[DataSingleton sharedSingleton] userLogin] within NSURLConnection block (in one of NetworkSingleton methods) - i get same time and in _userLogin i found some garbage =(

4:Bad solution

I spend about an hour and don't find correct answer for my question. And create this:

//DataSingleton.h
@interface DataSingleton : NSObject{
    NSString* _userLogin;
}

-(NSString*)userLogin;
-(void)setPrettyLogin:(NSString*)prettyLogin;
@end

and

//DataSingleton.m
#import "DataSingleton.h"

+(id)sharedSingleton{

    static dispatch_once_t DataSPred;
    static DataSingleton *shared = nil;
    dispatch_once(&DataSPred, ^{ shared = [[self alloc] init]; });
    return shared;
}

-(NSString*)userLogin{
    return _userLogin;
}

-(void)setPrettyLogin:(NSString*)prettyLogin{

    _userLogin = [prettyLogin retain];
    //I can,t release it and 
    //static code analysis is not happy with what is happening
}

@end

Are any one have the idea?

Best regards Sergey

Was it helpful?

Solution

You have to retain the value in the setter. Actually the problem has nothing to do with threading.

Your function is almost correct.

-(void)setPrettyLogin:(NSString*)prettyLogin {
    _userLogin = [prettyLogin retain];
}

But it should be

-(void)setPrettyLogin:(NSString*)prettyLogin {
    if (_userLogin != prettyLogin) {
         NSString *tmp = _userLogin;
         _userLogin = [prettyLogin retain];
         [tmp release];
    } 
}

-(void)dealloc {
    [_userLogin release];
    [super dealloc];
}

Now if you wan't to release the value call

[[DataSingleton sharedSingleton] setPrettyLogin:nil];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top