title: iOS Singleton Variables Not Keeping Their Values
body: <p>So I'm still kind of new to Objective-C, and this was my first app that I'm now updating. The idea is this: The whole app is basically various lists of stuff. It asks the API for 15 posts, shows those with a Load More button. Click Load More, it loads 15 more, etc. The API that it loads these from has a token system with a timeout built in. Too long between requests, and you have to get a new token. So I want to have a singleton to use anywhere in my app so I can just do <code>[APIMachine getToken]</code> and behind the scenes, it checks if the time since the last request was too long (or this is the first request), if so, gets a new token, otherwise returns the one we already have. I'm following the singleton pattern I've found in so many places, but every time the Load More button uses <code>[APIMachine getToken]</code>it gets either nothing or something completely random. I had it print this stuff in the logs, and one time I even got a UITableViewCell as my token. Looks like variables are being overwritten somehow. But I really can't figure it out. </p>
  
  <p>So here it is:</p>
  
  <pre><code>static PoorAPI2 *_instance;
  @implementation PoorAPI2
  
  @synthesize apiToken, timeOpened, tokenTTL;
  
  + (PoorAPI2*)sharedAPI
  {
  
      @synchronized(self) {
          if (_instance == nil) {         
              _instance = [[super allocWithZone:NULL] init];
          }
      }
      return _instance;
  }
  
  -(NSString *)API_open{
  
      //boring code to get api token redacted
  
  if ([doneness isEqualToString:@"success"]) {
      NSDictionary *data = [json objectForKey:@"data"];
      apiToken = [data objectForKey:@"api_token"];
      tokenTTL = [data objectForKey:@"ttl"];
      timeOpened = [NSDate date];
  
  }else{
      NSLog(@"FFFFFFFUUUUUUUUUUUU this error should be handled better.");
  }
  
  return apiToken;    
  }
  
  -(BOOL)isConnectionOpen{
      return ([timeOpened timeIntervalSinceNow]  &gt; tokenTTL);
  }
  
  -(NSString *)getToken{
      if([self isConnectionOpen]){
          return apiToken;
      }else{
          return [_instance API_open];
      }
  }
  
  -(id)init{
      if(self = [super init]){
          apiToken = [[NSString alloc] initWithString:@""];
          timeOpened = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
          tokenTTL = 0;
      }
      return self;
  }
  
  + (id)allocWithZone:(NSZone *)zone
  {   
      return [[self sharedAPI]retain];    
  }
  
  - (id)copyWithZone:(NSZone *)zone
  {
      return self;    
  }
  
  - (id)retain
  {   
      return self;    
  }
  
  - (unsigned)retainCount
  {
      return NSUIntegerMax;  //denotes an object that cannot be released
  }
  
  - (void)release
  {
      //do nothing
  }
  
  - (id)autorelease
  {
      return self;    
  }
  
  @end
  </code></pre>
  
  <p>I can only hope I'm doing something seriously foolish and this will be a hilarious point-and-laugh-at-that-guy thread. Then at least my app will work.</p>