Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 517 Vote(s) - 3.58 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Do I set properties to nil in dealloc when using ARC?

#1
I am trying to learn Automatic Reference Counting in iOS 5. Now the first part of this question should be easy:

1. Is it correct that I do **NOT** need to write explicit
release-property statements in my dealloc when using ARC? In other
words, is it true that the following does **NOT** need a explicit
dealloc?

@interface MyClass : NSObject
@property (strong, nonatomic) NSObject* myProperty;
@end

@implementation MyClass
@synthesize myProperty;
@end

2. My next and more important question comes from a line in the [Transitioning to ARC Release Notes][1] document:

> You do not have to (indeed cannot) release instance variables, but you may need to invoke [self setDelegate:nil] on system classes and other code that isn’t compiled using ARC.

This begs the question: how do I know which system classes are not compiled with ARC? When should I be creating my own dealloc and explicitly setting strongly retaining properties to nil? Should I assume all NS and UI framework classes used in properties require explicit deallocs?

There is a wealth of information on SO and elsewhere on the practices of releasing a property's backing ivar when using manual reference tracking, but relatively little about this when using ARC.


[1]:

[To see links please register here]

Reply

#2
**Short answer**: no, you do not have to nil out properties in `dealloc` under ARC.

**Long answer**: You should never nil out properties in `dealloc`, even in manual memory management.

In MRR, you should release your *ivars*. Nilling out properties means calling setters, which may invoke code that it shouldn't touch in `dealloc` (e.g. if your class, or a subclass, overrides the setter). Similarly it may trigger KVO notifications. Releasing the ivar instead avoids these undesired behaviors.

In ARC, the system automatically releases any ivars for you, so if that's all you're doing you don't even have to implement `dealloc`. However, if you have any non-object ivars that need special handling (e.g. allocated buffers that you need to `free()`) you still have to deal with those in `dealloc`.

Furthermore, if you've set yourself as the delegate of any objects, you should un-set that relationship in `dealloc` (this is the bit about calling `[obj setDelegate:nil]`). The note about doing this on classes that aren't compiled with ARC is a nod towards weak properties. If the class explicitly marks its `delegate` property as `weak` then you don't have to do this, because the nature of weak properties means it'll get nilled out for you. However if the property is marked `assign` then you should nil it out in your `dealloc`, otherwise the class is left with a dangling pointer and will likely crash if it tries to message its delegate. Note that this only applies to non-retained relationships, such as delegates.
Reply

#3
Just to give the opposite answer...

**Short answer**: no, you don't have to nil out auto-synthesized properties in `dealloc` under ARC. And you don't have to use the setter for those in `init`.

**Long answer**: You *should* nil out custom-synthesized properties in `dealloc`, even under ARC. And you should use the setter for those in `init`.

The point is your custom-synthesized properties should be safe and symmetrical regarding nullification.

A possible setter for a timer:

-(void)setTimer:(NSTimer *)timer
{
if (timer == _timer)
return;

[timer retain];
[_timer invalidate];
[_timer release];
_timer = timer;
[_timer fire];
}

A possible setter for a scrollview, tableview, webview, textfield, ...:

-(void)setScrollView:(UIScrollView *)scrollView
{
if (scrollView == _scrollView)
return;

[scrollView retain];
[_scrollView setDelegate:nil];
[_scrollView release];
_scrollView = scrollView;
[_scrollView setDelegate:self];
}

A possible setter for a KVO property:

-(void)setButton:(UIButton *)button
{
if (button == _button)
return;

[button retain];
[_button removeObserver:self forKeyPath:@"tintColor"];
[_button release];
_button = button;
[_button addObserver:self forKeyPath:@"tintColor" options:(NSKeyValueObservingOptions)0 context:NULL];
}

Then you don't have to duplicate any code for `dealloc`, `didReceiveMemoryWarning`, `viewDidUnload`, ... and your property can safely be made public. If you were worried about nil out properties in `dealloc`, then it might be time you check again your setters.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through