Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

performSelector: afterDelay: without retaining the target?

I've got a class which uses NSURLConnection to open a long-running connection to a server. When the connection's closed, either in connectionDidFinishLoading: or connection:didFailWithError:, I want to wait 15 seconds then retry the connection.

At the moment I'm using [self performSelector:@selector(restartConection) withObject:nil afterDelay:15.0];, but this leads to the undesired situation that when the object is released by its creator, the performSelector and NSURLConnections perpetually retain 'self', and it never gets deallocated.

How can I do this without perpetually retaining the object? Any help'd be much appreciated.

Thanks, -Alec

like image 915
Max Avatar asked Jan 15 '12 21:01

Max


2 Answers

I think your only option is to send

[NSTimer cancelPreviousPerformRequestsWithTarget: object];

at some point, probably, before releasing the object. If the timer hasn't been scheduled, this is a no-op, but is not free performance-wise.

like image 191
Costique Avatar answered Nov 15 '22 21:11

Costique


You cannot avoid retaining the object. It is retained in order to save you from ugly crashes when in the next main loop cycle the runtime is going to call your selector on the released object.

If you really insist on having your object released immediately without waiting for your delayed selector, I would suggest you to create a separate proxy class. Say your class is called A, create proxy class B which will have a weak reference to your class A (i.e. __weak A* a) and restartConnection selector which will check if the weak reference is valid. If so it would invoke restartConnection on your A object. Then, do, of course, a delayed selector on B's restartConnection

But first of all, I would really suggest that you reevaluate whether you really cannot live with the retain.

like image 5
Krizz Avatar answered Nov 15 '22 19:11

Krizz