1
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 方法中释放。是对的吗?

4

5 回答 5

0

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

- (void)dealloc {

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

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

于 2011-03-17T06:34:24.107 回答
0

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

我们为什么要释放?

于 2011-03-17T06:36:31.670 回答
0

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

self.view = nil;

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

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

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

于 2011-03-17T08:11:26.083 回答
0

我认为只有第三个变量必须在 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?
}

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

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

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

于 2011-03-17T08:55:25.287 回答
-2

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

在你的交易中

[array release];
self.array=nil;
self.scopeBar=nil;
self.view=nil;
于 2011-03-17T08:01:56.073 回答