我想知道释放变量

发布于 2024-10-22 06:25:34 字数 599 浏览 7 评论 0原文

UIView *view; //1

UISegmentedControl *scopeBar; //2

NSMutableArray *array; //3

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

@property (nonatomic, retain) UISegmentedControl *scopeBar;

@property (nonatomic, retain) NSMutableArray *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 {
}

我认为只有第三个变量需要在 dealloc 方法中释放。 是这样吗?

UIView *view; //1

UISegmentedControl *scopeBar; //2

NSMutableArray *array; //3

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

@property (nonatomic, retain) UISegmentedControl *scopeBar;

@property (nonatomic, retain) NSMutableArray *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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笔落惊风雨 2024-10-29 06:25:34

是的,(array 需要被释放),因为你alloc 它。因此,释放它是程序员的责任。因此 -

- (void)dealloc {

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

有关发布内容的更多信息,内存管理-ObjectiveC

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

岁月流歌 2024-10-29 06:25:34

我认为您会在这个问题中找到关于您的查询的好建议

我们为什么应该发布?

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

Why should we release?

弥枳 2024-10-29 06:25:34

与某些答案相反,您还必须释放您的插座(视图),不仅在 dealloc 中而且在 viewDidUnload 中,最简单的方法是将其设置为 nil :

self.view = nil;

另请注意,如果您不访问属性,但访问实例变量(即没有 self. 前缀),则保留属性将无法帮助您并且您没有保留该对象。这意味着一旦 scopeBarview 的子视图中删除,它就会被释放,并且您最终会访问僵尸。

根据经验,最好在除 init 方法之外的任何地方使用属性访问器,这样您就不必显式处理内存管理。如果是出口,则在 dealloc 和 viewDidUnload 中将它们设置为 nil 就足够了。

另外,不要按照 Jenifer 的建议去做,一旦你调用了变量的释放,不要将该属性设置为 nil,否则会过度释放它。

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.

幸福还没到 2024-10-29 06:25:34

我认为只有第三个变量需要在dealloc方法中释放。是这样吗?

// 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?
}

其他答案假设悬挂指针(例如,您仍然持有一个用于查看的指针,尽管视图可能在您背后发生了变化)是允许的。

它们不应该被允许出现在实际的程序中。它们非常危险,并且很难重现它们造成的错误。因此,您必须确保您拥有对您维护/持有的指针的引用。

为了子类化,您还应该在公共接口中使用访问器 - 以防它们覆盖它们。如果您不想允许/支持这一点,请考虑简单地使用私有变量。

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.

把时间冻结 2024-10-29 06:25:34

我认为你应该释放它们并将它们设置为零,因为你已经将它们设置为属性,所以这样做:-

在你的 dealloc 中

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文