Domanda

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

È stato utile?

Soluzione

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];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top