【问题标题】:- (void)dealloc Question- (void)dealloc 问题
【发布时间】:2010-12-30 01:03:48
【问题描述】:

您能告诉我以下代码是否 100% 正确吗?特别是dealloc 部分

FirstViewController.h

#import <UIKit/UIKit.h>
#import "SecondViewController.h"

@class SecondViewController

@interface FirstViewController : UIViewController
{
    SecondViewController   *SecondController;
}

- (IBAction)SwitchView;

@property (nonatomic, retain) IBOutlet SecondViewController *SecondController;

@end

FirstViewController.m

#import "FirstViewController.h"

@implementation FirstViewController

@synthesize SecondController;

- (IBAction)SwitchView
{    
    SecondController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    SecondController.modalTransitionStyle = UIModalPresentationFullScreen;
    [self presentModalViewController:SecondController animated:YES];
    [SecondController release];
}

/// OTHER CODE HERE ///

- (void)dealloc
{
    [SecondController release];
    [super dealloc];
}

@end

谢谢!

【问题讨论】:

  • 一个问题,谁负责解散 SecondController 实例?
  • 你真的真的不想调用你的实例变量SecondController。叫它secondController。我很惊讶编译器甚至编译了该代码。
  • @bbum 为什么编译器会检查变量大小写和/或拼写?!
  • 我将SecondControllerSecondViewController 读为同一件事;我的错。但也说明了为什么实例变量应始终以小写字母开头。静态分析器应该标记这个。
  • @mvds:我认为@bbum 遵循惯例,即实例变量通常为小写,以便轻松将它们与类标识符区分开来。

标签: iphone objective-c ios memory-management


【解决方案1】:

不,这是不正确的。您将release 消息发送到dealloc 中的指针,但该指针可能不再指向SecondController。这可能会导致一些非常奇怪的错误,通常是随机对象被释放。

在 Objective-c 术语中,您的类不保留(认为“拥有”)SecondController,因此它不应该首先尝试在dealloc 上释放它。

要以正确的方式声明和释放所有权,请这样做:

- (IBAction)SwitchView
{    
    self.SecondController = [[[SecondViewController alloc] 
                  initWithNibName:@"SecondViewController" bundle:nil] autorelease];
    self.SecondController.modalTransitionStyle = UIModalPresentationFullScreen;
    [self presentModalViewController:self.SecondController animated:YES];
}

/// OTHER CODE HERE ///

- (void)dealloc
{
    self.SecondController = nil;
    [super dealloc];
}

这也将保护您免受SwitchViewdealloc 之间发生的任何其他事情的影响。 (只要那东西遵守规则并使用self.SecondController = ...更改属性)

SwitchView 中,alloc/autorelease 序列使您的例程在例程的长度(以及稍长一点)内保持所有权。 self.SecondController = 部分确保您的类保留 SecondController 对象,因为您声明了 (nonatomic,retain)

【讨论】:

    【解决方案2】:

    您应该使用属性设置器来分配SecondController

    我建议你只 alloc/init 那个视图控制器一次,然后在 SwitchView 显示它:

    #import "FirstViewController.h"
    
    @implementation FirstViewController
    
    - (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle {
       if((self = [super initWithNibName:nibName bundle:nibBundle])) {
          self.SecondController = [[[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil] autorelease];
          SecondController.modalTransitionStyle = UIModalPresentationFullScreen;
       }
       return self;
    }
    
    - (IBAction)SwitchView
    {    
        [self presentModalViewController:SecondController animated:YES];
    }
    
    /// OTHER CODE HERE ///
    
    - (void)dealloc
    {
        [SecondController release];
        [super dealloc];
    }
    
    @end
    

    这样,您实际上只创建了一次 SecondController 视图控制器,而不是每次调用 -SwitchView 时创建它。

    【讨论】:

    • 请注意,您不一定希望在此控制器加载时实例化 secondviewcontroller:如果您经常这样做,应用程序启动会变慢。如果你沿着这条路走,也许还可以考虑从一个 nib 初始化所有东西(是的,这既是 FirstViewController 也是 SecondViewController - 只需将 UIViewController 添加到 FirstViewController nib 并将类名称更改为 SecondViewController)
    猜你喜欢
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多