ios SDK开发之关于IBOutlet对象的释放

          虽然笔者不用Xib,不过同事在工作中很喜欢用,关于IBOutlet对象的释放,笔者一直比较疑惑。曾经笔者在负责内存泄露查找这块工作的时候,碰到类似以下的情况,见代码:

@interface TestController : UIViewController {
IBOutlet UIImageView *imageView;
IBOutlet UIButton *button;
}

@property (nonatomic, retain) IBOutlet UILabel *titleLabel;
@property (nonatomic, retain) NSObject *object;

@end

@implementation TestController
@synthesize titleLabel, object;


- (void)dealloc {
self.titleLabel;
self.object = nil;
[imageView release],imageView = nil;
[button release],button = nil;
[super dealloc];
}
      关于titleLabel和object对象需要在dealloc函数中释放,相信大家都没啥争议的,在此仅列出做一个对比。本文重点要讨论的是上述代码中的imageView、button对象的释放问题,到底这两个对象需不需要在dealloc函数中release呢?

      针对上述代码情况,这个问题的答案,有点复杂。需要分两种情况考虑,如果你编译的是一个Mac OS X的应用,那么你不需要在dealloc函数中release上述两个IBoutlet对象;如果你编译的是一个iOS系统的应用,那么恭喜你,上述代码是正确的,否则会导致内存泄露。

      这跟IBoutlet对象在Mac OS X和iOS系统中内部不同的运行机制有关。

      在Mac OS X中,IBOutlet对象内部机制如下:

       1、系统在TestController对象中查找一个set方法,比如:- (void)setImageView:(UIImageView *)imageView,如果该方法存在,调用来设置IBoutlet对象。

       2、如果不存在步骤1中的set方法,那么查找一个名为IBoutlet对象名的实例对象,set 该实例对象,并且没对该实例对象进行retain操作。

     在iOS系统中,IBoutlet对象内部设置机制如下:

      1、在TestController的对象实例中调用 [self setValue:outletValue forKey:@"OutletName"];

    2、在TestController的对象实例中查找一个set方法, 比如:- (void)setImageView:(UIImageView *)imageView,如果该方法存在,调用来设置IBoutlet对象。

     3、如果不存在步骤2中的set方法,那么查找一个名为IBoutlet对象名的实例对象,set 该实例对象,并且对该实例对象进行retain操作。

    显然,按照上述运行机制,在Mac OS X中,本文开头的IBoutlet imageView和button实例都走了步骤2,所以不需要在dealloc函数中release IBoutlet实例对象;而在iOS系统中,本文开头的IBoutlet imageView和button实例都走了步骤3,所以需要在dealloc函数中release IBoutlet实例对象。

   再次看下面的代码:

  

@interface TestController : UIViewController {
IBOutlet UIImageView *imageView;
IBOutlet UIButton *button;
}

@property (nonatomic, retain) IBOutlet UILabel *titleLabel;
@property (nonatomic, retain) NSObject *object;

@end

@implementation TestController
@synthesize titleLabel, object;


- (void)dealloc {
self.titleLabel;
self.object = nil;
[imageView release],imageView = nil;
button = nil;
[super dealloc];
}

- (void)setImageView:(UIImageView *)pImageView {
    if (imageView != pImageView) {
          [imageView release];
          imageView = [pImageView retain];
 }
}


- (void)setButton:(UIButton *)btn {
  if (button != btn) {
     button = btn;
  } 
}


        如果将本文开头的代码改成这样,那么 就需要根据自己的set方法的具体情况分别处理是否需要release了。显然上述代码中,imageView需要在dealloc函数中release,button实例对象就不需要在dealloc函数中release了。

        ok,本文结束~~~





猜你喜欢

转载自blog.csdn.net/eric_XJJ/article/details/8770299