views:

324

answers:

3

I have app that performs login to web service and then requests list of objects using sessionid received during Login.

Appdelegate.h

....
@property (nonatomic, retain) NSString *sessionId;

AppDelegate.m:

-(id)init{
     queue = [[NSOperationQueue alloc] init];
     [queue setMaxConcurrentOperationCount:1];
.....
}

- (void)applicationDidFinishLaunching:(UIApplication *)application {
        LoginOperation *loginOperation = [[LoginOperation alloc] init];
     [queue addOperation:loginOperation];
     [loginOperation release];
      ListOperation *listOperation = [[ListOperation alloc] init];
      [queue addOperation:listOperation];
      [listOperation release];

}

LoginOperation:

-(void) main {
...
[[UIApplication sharedApplication] delegate] setSessionId:sessionID];
...

}

ListOperation:

-(void)main{
//Crashes at next line:
NSString *sessionId = [[UIApplication sharedApplication] delegate] sessionId] ;
}

It crash if I acces s any proeprty in any singleton object or AppDelegate. Debugger shows that singleton object or Appdelegate is valid and initialized but ANY property of that object is invalid and access leads to crash.

This is some strange threading-related gotcha. The only thing I can think of is that NSOperation has invalid copies of all other objects in it's thread or something like that.

It doesn't crash if doing same in manually spawned thread using [NSThread detachNewThreadSelector:@selector(performList) toTarget:self withObject:nil]; I want to use NSOperation instead of NSThread detach... because NSOperation provides queue.

What is the optimal pattern for such situation? defining ListOperation as Concurrent Operation? I don't want complicated mess with defining Concurrent Operation.

I think my case is fairly simple and there should be simple solution?

A: 

You can add one operation as a dependency for another. The other is then guaranteed not to execute until after the dependent operation completes. Also, anywhere you use the sessionID in your code, you should ensure that the Login operation has already completed. An example of adding dependencies based on your code:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
      LoginOperation *loginOperation = [[LoginOperation alloc] init];
      ListOperation *listOperation = [[ListOperation alloc] init];
      [listOperation addDependency:loginOperation];
      [queue addOperation:loginOperation];
      [queue addOperation:listOperation];
      [loginOperation release];
      [listOperation release];
}

Now, listOperation definitely will not execute until loginOperation completes.

Jason Coco
Thanks for the hint.However it doesn't solve my problem with accessing sessionID from inside of NSOperation.
Rod
A: 

Turn on zombies (NSZombieEnabled environment variable) to see if you are overfreeing.

Log the [[[UIApplication sharedApplication] delegate] sessionId] to verify what it is before the stringWithString (if it was nil, that would raise an exception).

Speaking of which, [NSString stringWithString:xxx] does absolutely nothing useful. Whatever you are trying to acomplish with that, it isn't going to help - reread the memory management rules.

Add an NSLog at the start/end of each main to verify they are syncronous as you expect.

And "it crashes" really is a bit too vague for a question, please include more details of the crash backtrack.

Peter N Lewis
Logging [[[UIApplication sharedApplication] delegate] sessionId] results in BAD ACCESS crash.But Appdelegate is valid object!Very strange issue this is.
Rod
@Roman - That means that your sessionID property is being overreleased. As bbum asked, post the code where you are creating the actual sessionID.
Jason Coco
Turn on NSZombieEnabled (in your Executable settings, Arguments panel, add an environment variable NSZombieEnabled = YES. Also, edit your question and show ALL the code that refers to sessionID. Chances are you are mishandling it.
Peter N Lewis
A: 

Try using zombies within Instruments. Really helpful link that helped me track down leaks before. Not sure how effective this will be in a threaded scenario.

http://www.markj.net/iphone-memory-debug-nszombie/

SummaGuy2023