开发者

I wonder about releasing variables

UIView *view; //1

UISegmentedControl *scopeBar; //2

NSMutableArray *array; //3

@property (nonatomic, retain) IBOutlet UIView *view;

@property (nonatomic, retain) UISegmentedControl *scopeBar;

@property (nonatomic, retain) NSMutableA开发者_如何转开发rray *array;

.m

@synthesize view, scopeBar, array;

    for (id subView in [view subviews]) {
        if ([subView isMemberOfClass:[UISegmentedControl class]]) {
            scopeBar = (UISegmentedControl *)subView;
        }
    }

array = [[NSMutableArray alloc] init];

- (void)dealloc {
}

I think that only the third of the variables has to be released in the dealloc method. Is that right?


Yes, (array needs to be released) because you alloc it. So, it's programmer's responsibility to release it. So -

- (void)dealloc {

    [ array release ] ;
    // Any other resources alloc, init, new should be released
}

For more info on what to release, Memory management - ObjectiveC


And I think you will find good suggestions in this question about your query

Why should we release?


Contrary to some of the answers, you have to release your outlet (view) as well, and not only in the dealloc but also in the viewDidUnload, the easiest way is to set it to nil :

self.view = nil;

Also note that if you don't access your properties but your instance variables (i.e. without self. prefix) your retain attribute won't help you and you are not retaining the object. That means that as soon as scopeBar would be removed out of the subViews of the view, it will be released and you end up accessing a zombie.

As a rule of thumb, it's best to use the properties accessor everywhere except in the init methods so that you don't have to deal with the memory management explicitly. Setting them to nil in the dealloc and viewDidUnload in case of outlets should be enough then.

Also, don't do what Jenifer suggested and once you've called a release on a variable, don't set the property to nil, that would overrelease it.


I think that only the third of the variables has to be released in the dealloc method. Is that right?

// no. your dealloc should look like this:

- (void)dealloc {
    // note: *not* using accessors in dealloc
    [view release], view = nil;
    [scopeBar release], scopeBar = nil;
    [array release], array = nil;
    [super dealloc];
}

// your assignment of `scopeBar` should look like this:
...
self.scopeBar = (UISegmentedControl *)subView;
...
// you want to retain the view, as advertised.
// consider avoiding an ivar if you can easily access it.


// your assignment of `view` should look like this:
...
self.view = theView;
...
// you want to retain the view, as advertised.
// consider avoiding an ivar if you can easily access it.



// your assignment of `array` should look like this in your initializer:
// note: *not* using accessors in initializer
...
// identical to `array = [[NSMutableArray alloc] init];`
array = [NSMutableArray new];
...


// and the assignment of `array` should look like this in other areas:
...
self.array = [NSMutableArray array];
...


// you're likely to be best suited to declare your array as
// follows (assuming you really need a mutable array):
...
NSMutableArray *array; // << the declaration of the ivar
...

...
// the declaration of the public accessors.
// note the array is copied, and passed/returned as NSArray
@property (nonatomic, copy) NSArray *array;
...


// finally, the implementation manual of the properties:
- (NSArray *)array {
    // copy+autorelease is optional, but a good safety measure
    return [[array copy] autorelease];
}

- (void)setArray:(NSArray *)arg { 
    NSMutableArray * cp = [arg mutableCopy];
    // lock? notify?
    NSMutableArray * prev = array;
    array = cp;
    [prev release], prev = nil;
    // unlock? notify? update?
}

other answers assume that dangling pointers (e.g., you still hold a pointer to view, although the view may have changed behind your back) are allowable.

they should not be allowed in real programs. they are extremely dangerous, and it can very difficult to reproduce errors they cause. therefore, you must ensure you own a reference to the pointers you maintain/hold.

you should also use the accessors in the public interface for the subclasser's sake - in case they override them. if you don't want to allow/support that, consider simply using a private variable.


As i think you should release and set them nil because you have made them properties so do this:-

in your dealloc

[array release];
self.array=nil;
self.scopeBar=nil;
self.view=nil;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜