【问题标题】:iPhone dev - viewDidLoad and viewDidUnload in programmatically created view?iPhone 开发 - 以编程方式创建的视图中的 viewDidLoad 和 viewDidUnload?
【发布时间】:2010-06-02 15:28:54
【问题描述】:

我在某处读到,在 UIViewController 中以编程方式创建的视图中,不使用 Interface Builder,不应使用 -viewDidLoad 和 -viewDidUnload。这是正确的吗?为什么?我将在哪里发布我保留属性的子视图?还是我不应该为它们使用属性?

编辑:阅读我对 Rob Napier 的回答的 cmets。

【问题讨论】:

    标签: iphone memory-management uiviewcontroller viewdidload


    【解决方案1】:

    在-viewDidLoad 中创建您的子视图。如果您需要它们的 ivars,则只需分配它们的值。通过将视图作为子视图添加到主视图来保持引用。

    然后,当您的视图被卸载时,您应该将您的 ivars 设置为 nil,因为自从您的视图被删除和释放后,该对象已被释放。

    所以在你的标题中

    @interface MyViewController : UIViewController {
      IBOutlet UIView *someSubview; // assigned
    }
    @property (nonatomic, assign) IBOutlet UIView someSubview;
    @end
    

    在你的实现中

    @implementation MyViewController
    //... some important stuff
    
    - (void)viewDidLoad;
    {
      [super viewDidLoad];
      someSubview = [[UIView alloc] initWithFrame:self.view.bounds];
      [self.view addSubview:someSubview]; // retains someSubview
      [someSubview release];   // we don't hold it
    }
    
    - (void)viewDidUnload;
    {
      [super viewDidUnload];
      someSubview = nil;  // set the pointer to nil because someSubview has been released
    }
    
    //... more important stuff
    
    @end
    

    如果你希望你也不能在-viewDidLoad 中释放someSubview,但是你必须在-viewDidUnload 和-dealloc 中释放它,因为(如果我没记错的话)-viewDidUnload 在@ 之前没有被调用987654329@。但如果您不保留someSubview,则无需这样做。

    【讨论】:

    • 我认为使用保留属性更常见,但我没有使用 Interface Builder 所以没有 IBOutlet。通常我什至不使用属性,除非我需要公开这些值,或者它们是延迟加载的。我了解内存管理以及在哪些方法中放置什么。感谢您的回答。
    • 我知道视图保留了它的子视图,但是AFAIK的一般方法是使用保留属性,在-viewDidUnload中将它们设置为nil,在dealloc中释放。
    • 在没有属性的情况下通过nib加载设置IBOutlets是否保留或分配有官方规定吗?
    • 好吧,如果您的代码中没有引用它,那么它的内存管理将不是您的责任,但就像我说的那样,我没有使用 Interface Builder。
    【解决方案2】:

    这里的奇怪之处在于,未从 NIB 文件加载的 UIViewController 不会收到有关其视图卸载的通知(因此不会调用其 viewDidUnload 方法),除非您提供 loadView 方法的基本实现,例如:

    - (void)loadView {
       self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds] autorelease];
       [self.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    }
    
    - (void)viewDidLoad {
       [super viewDidLoad];
       // create views...
    }
    
    
    - (void)viewDidUnload {
       // destroy views...
       [super viewDidUnload];
    }
    

    这只发生在基本 UIViewController,例如 UITableViewController 不需要使用此解决方法进行修复。

    所以罗布斯是对的。

    【讨论】:

      猜你喜欢
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      相关资源
      最近更新 更多