Do we really need a safe release macro?

Quite a lot of people seem to use a macro, for example

#define SAFE_RELEASE(X) [X release]; X = nil; 

(including me).

I am reviewing why I use it, and I would like some opinion on the canvas.

The goal (I think) to use this macro is that if you accidentally used your object after it was released, then you would not get a bad access exception, because objective-c would rather happily ignore it when the object is zero.

It seems to me that this may mask some obscure errors. Perhaps, in fact, it would be preferable if the program worked when you try to use X again. Thus, during testing, you can find the problem and improve the code.

Does this macro support lazy programming?

Thoughts?

+6
objective-c
source share
5 answers

I think you will discuss all the pros and cons in your question, so I have nothing to add. Personally, I do not use the construct. As you can imagine, it can be used for paper over areas where people do not understand the correctness of memory management. I prefer to correct the error rather than the symptom.

However, one compromise I've seen from time to time:

  • Fix error during development
  • Do var = nil; in production code

Thus, it can be more reliable with customer payment and still crash during development.

I'm also not interested in this, since you use different code for your users, and just because working with the buggy continues to work, this does not mean that it is doing the right thing. Not crashing but corrupting your database unwanted behavior ...

+6
source share

I think this is equivalent, e.g. self.myVar = nil, where applicable, is good. There are many cases where you simply cannot simply assign nil and assume that any subsequent access is a mistake.

For example, in UIKit, this is a good behavior to free up as many resources as possible when the OS asks. For example.

 - (void)didReceiveMemoryWarning { [myCachedData release]; [super didReceiveMemoryWarning]; } 

Now that my class is used as follows, how do I know that myCachedData is now invalid? The only way (without an ANOTHER variable acting as a flag) is to set myCachedData to zero after it is released. And the condensation of these two tedious lines into one is exactly what SAFE_RELEASE is for.

+2
source share

You do not need , but it is convenient. I use something similar in my applications. You may consider this β€œlazy”, but when you have about 20 objects somewhere, manually recording them becomes tedious.

+1
source share

I studied the same question. With a bit of reading I did, I have something like this:

 #define DEBUGGING //#define PRODUCTION #ifdef DEBUGGING #define SAFE_RELEASE(X) [X release]; #else #define SAFE_RELEASE(X) [X release]; X = nil; #endif 

That way, if I develop, I get Crashes. In production, I do not.

Scott <-

+1
source share

As Andrey noted, there are cases when assigning nil not only eliminates errors, but is also necessary. Just review typical UIViewController code

 - (void)viewDidLoad { button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; // autoreleased [button retain]; // keep alive } - (void)viewDidUnload { // view has been removed [button release]; } - (void)dealloc { // destroying the view controller [button release]; // <-- problem } 

In case the controller is loaded, later unloaded (because another view controller is displayed, the memory is low) and finally destroyed, the [button release] in dealloc will re-issue the button (send a message to the released object). Therefore, you must assign nil. A safe solution would be:

 - (void)viewDidUnload { // view has been removed [button release]; button = nil; } - (void)dealloc { // destroying the view controller [button release]; // <-- safe } 

In these cases, the macro is good and useful. To be more explicit in what he is doing, better call him RELEASE_AND_NIL

 #define RELEASE_AND_NIL(X) [X release]; X = nil; 
+1
source share

All Articles