【问题标题】:I wonder about releasing variables我想知道释放变量
【发布时间】:2011-03-17 06:30:54
【问题描述】:
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 方法中释放。 对吗?

【问题讨论】:

    标签: objective-c release dealloc


    【解决方案1】:

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

    - (void)dealloc {
    
        [ array release ] ;
        // Any other resources alloc, init, new should be released
    }
    

    有关发布内容的更多信息,Memory management - ObjectiveC

    【讨论】:

      【解决方案2】:

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

      Why should we release?

      【讨论】:

        【解决方案3】:

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

        self.view = nil;

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

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

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

        【讨论】:

          【解决方案4】:

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

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

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

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

          【讨论】:

            【解决方案5】:

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

            在你的交易中

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

            【讨论】:

            • 要么发布(并且可以选择将 ivar 设置为 nil),要么调用 setter - 永远不要同时使用!
            猜你喜欢
            • 1970-01-01
            • 2011-03-30
            • 1970-01-01
            • 1970-01-01
            • 2020-03-24
            • 2011-01-12
            • 2011-03-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多