问题
I have a simple query that I'd like cleared up by someone... Is it bad-practice to retain self?
I have a server request object that I'd like to make. I'd like to be able to use it in the following fashion:
ARequest *request = [ARequest request: someParam];
request.delegate = self;
[request begin];
In order for the object not to self destruct as soon as the autorelease pool is drained, I imagine I need to call a retain in it's init method and then a release once the server response has been received, processed and delivered to it's delegate.
However, something is raising a warning bell in my head with this approach. Better ways to do it?
回答1:
There is nothing wrong with retaining self
, as long as you release it at some well-defined point in accordance with normal memory management protocol. If an object requires itself to exist until some condition is met, it should take responsibility for that, in the same way as it does for any other object it requires to continue existing.
Introducing otherwise extraneous manager objects or foisting the responsibility off on the object’s owner for superstitious reasons would be the real anti-pattern here.
(The equivalent approach in garbage-collected code would be for the object to exclude itself from garbage collection while results are pending, or root it through a collection of some sort if you dislike that idea.)
回答2:
It's not unheard-of, but it is somewhat uncommon. The main way I've seen it used (and used it myself) is when you're dealing with some sort of semi-synchronous object (by semi-synchronous I mean that it does not block the main thread, but it also does not execute on a background thread; an NSURLConnection
would fit this bill). For example, I wrote a subclass of NSWindowController
that was specifically for displaying a window as a sheet and for invoking some certain delegate callbacks. Basically, you'd alloc
/init
a new sheet controller and invoke beginSheetForWindow:
. This would run the sheet semi-synchronously, and then invoke an appropriate callback when the sheet was dismissed.
Since the invoking object doesn't necessarily "own" the sheet (think of it as a Mac version of a modal view controller on iOS), the sheet controller does [self retain]
immediately before showing the sheet, and [self release]
immediately after cleaning up and invoking callbacks. The purpose behind this was to ensure that the controller object would stick around until the sheet was done. (The sheet, IIRC, was retained by the runloop, but I also needed the controller to stick around)
Like I said, it's very rare to come across a situation where you would want to [self retain]
, but it's not impossible. However, as a general rule of thumb, if you think that you need to [self retain]
, you may want to think again.
回答3:
Easiest way to do this would be to create an iVar for your request, retain the request when you start it and release it when the last delegate method is called.
Is ARequest
a class you created? Does it create a new thread to asynchronously submit the request?
回答4:
I once did the same thing as you. I wrote a Category-Method on NSString to send it it to a server, that will print it. In the Category-Method I had to call [self retain]
, so that the callback methods could be a NSString-Categroy-Method to.
I felt so bad about it, that I rewrote everything to use a Singleton, that is accessed by the Category-Method. So the Singleton will retain the string as long as necessary.
来源:https://stackoverflow.com/questions/3953413/bad-practice-to-retain-self