views:

201

answers:

2

Hi,

I've been experiencing memory problems (the app will run for a couple of iterations, then receive low memory warning and finally be terminated) while working with NSInvocationOperation in a method called repeatedly by a NSTimer.

The method will be called every 1/4 of a second and I've narrowed down the source of the problem to the following test lines:

-(void)methodCalledByTimer {

        NSInvocationOperation *o = [NSInvocationOperation alloc];
        [o release];

}

Uncommenting these two lines (to produce an empty method) will prevent the memory problems from arising. Once they are in, memory usage will increase quite fast and finally the app will be terminated.

Can anybody explain what I'm doing wrong here? Do I have to do anything else to make sure, that the NSInvocationOperation object will be properly released?

Thank you very much in avance for your help.

Kind regards, Michael.

A: 

A possible solution might be to just store your NSInvocationOperation somewhere else instead of creating and releasing one each time methodCalledByTimer is called.

I was having problems with NSCalendar where I would create and release one thousands of times to be used for some date work, but I then just created one calendar attached to the appDelegate and accessed that every time. Fixed a ton of memory leaks, and it's probably better than creating a new object every single time.

mjdth
Do you know if I can really reuse NSInvocationOperation objects? I am adding the object to a NSOperationQueue and had the queue take care of the operation once it finished. So to keep the operation and reuse it, I'd retain it somewhere and "reinit" it with initWithTarget:selector:object for a second run? Not sure, if that will really work, but I might give it a shot and let you know if it works. Thanks for the quick feedback!
Michael Liebwein
A: 

I believe the problem lies in how you allocate without initializing. The first of the buggy lines should read:

NSInvocationOperation *o = [[NSInvocationOperation alloc] initWithTarget:yourTarget selector:@selector(yourSelector) object:yourObjectOrNil];

Regarding mjdth's answer, I believe you should not attempt to reuse an invocation operation. From the documentation of NSOperation (the superclass of NSInvoationOperation):

"An operation object is a single-shot object—that is, it executes its task once and cannot be used to execute it again."

Furthermore, no Objective-C object should ever be initialized twice.

MW