Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSOperation inside NSOperationQueue not being executed

I really need help here. I'm desperate at this point.

I have NSOperation that when added to the NSOperationQueue is not being triggered. I added some logging to see the NSOperation status and this is the result:

Queue operations count = 1
Queue isSuspended = 0
Operation isCancelled? = 0
Operation isConcurrent? = 0
Operation isFinished? = 0
Operation isExecuted? = 0
Operation isReady? = 1
Operation dependencies? = 0

The code is very simple. Nothing special.

       LoadingConflictEvents_iPad *loadingEvents = [[LoadingConflictEvents_iPad alloc] initWithNibName:@"LoadingConflictEvents_iPad" bundle:[NSBundle mainBundle]];

       loadingEvents.modalPresentationStyle = UIModalPresentationFormSheet;
       loadingEvents.conflictOpDelegate = self;

       [self presentModalViewController:loadingEvents animated:NO];

       [loadingEvents release];

       ConflictEventOperation *operation = [[ConflictEventOperation alloc] initWithParameters:wiLr.formNumber pWI_ID:wiLr.wi_id];

       [queue addOperation:operation];           

       NSLog(@"Queue operations count = %d",[queue operationCount]);
       NSLog(@"Queue isSuspended = %d",[queue isSuspended]);
       NSLog(@"Operation isCancelled? = %d",[operation isCancelled]);
       NSLog(@"Operation isConcurrent? = %d",[operation isConcurrent]);
       NSLog(@"Operation isFinished? = %d",[operation isFinished]);
       NSLog(@"Operation isExecuted? = %d",[operation isExecuting]);
       NSLog(@"Operation isReady? = %d",[operation isReady]);
       NSLog(@"Operation dependencies? = %d",[[operation dependencies] count]);


       [operation release];

Now my operation do many things on the main method, but the problem is never being called. The main is never executed. The most weird thing (believe me, I'm not crazy .. yet). If I put a break point in any NSLog line or in the creation of the operation the main method will be called and everything will work perfectly.

This have been working fine for a long time. I have been making some changes recently and apparently something screw things up. One of those changes was to upgrade the device to iOS 5.1 SDK (iPad).

To add something, I have the iPhone (iOS 5.1) version of this application that use the same NSOperation object. The difference is in the UI only, and everything works fine.

Oh, and this only fails on the actual device. In the simulator everything works ok.

Any help will be really appreciated.

Regards,

like image 727
Martin Garcia Avatar asked Mar 26 '12 17:03

Martin Garcia


3 Answers

If the operation is concurrent, you need to implement -start, not -main.

like image 149
jsd Avatar answered Nov 19 '22 19:11

jsd


I had the same issue, but the resolution to mine was not the same, so I thought I'd throw my answer in here too for future people like me.

My problem was that in my NSOperation subclass, I had:

@property CGPoint start;

which, when synthesized, creates the method:

-(CGPoint)start

which overrides NSOperation's -(void)start; method, which is the signifier for a non-concurrent NSOperation, and was preventing all the regular stuff that goes on in -(void)start from happening, which thus prevents the -(void)main method from being called at all.

Once I renamed my property to something other than start, it worked fine.

like image 43
commanda Avatar answered Nov 19 '22 19:11

commanda


Ok, I finally solve this issue.

The problem I was having was due to an NSOperation running in the background all the time (but in a different queue). This operation was blocking any other thread (NSOperation) to be executed. This was happening only in iPad 1 because is not dual core.

My NSOperation was doing something like this on the main method:

- (void)main 
{
    while (![self isCancelled]) {
        //Do stuff
    }
}

And the NSOperation was contantly doing it the whole time

Silly me, I didn't give the OS time to work with other threads, so adding a sleep made the trick

- (void)main
{
    while (![self isCancelled]) {
        [NSThread sleepForTimeInterval:0.5];
        //Do Stuff
    }
}

That sleep gives the OS chance to work with other threads.

Why putting a breakpoint was doing the work? ... the debugger stopped all the threads and because the breakpoint was in my other NSOperation, that thread was executed.

like image 4
Martin Garcia Avatar answered Nov 19 '22 19:11

Martin Garcia