【问题标题】:releasing objects?释放物体?
【发布时间】:2011-06-28 21:32:26
【问题描述】:

我对 iPhone 编程真的很陌生。

这个应用程序是一个简单的测验。 FirstAppDelegate.m 创建一个 QuizViewController 实例并将其视图添加到窗口中。

#import "FirstAppDelegate.h"
#import "ResultViewController.h"
#import "QuizViewController.h"

@implementation FirstAppDelegate

@synthesize window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {
    UIViewController *vc = [[QuizViewController alloc] init];
    [window addSubview:[vc view]];
    [window makeKeyAndVisible];
    [vc release];

    return YES;
}

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

@end

我想我可以像我听到的那样释放 vc,因为 window 会保留它(?)但它产生了一个错误:

2011-06-28 23:06:34.190 First[14289:207] -[__NSCFType foo:]: unrecognized selector sent to instance 0x4e1fc90
2011-06-28 23:06:34.193 First[14289:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType foo:]: unrecognized selector sent to instance 0x4e1fc90'

...所以我评论了它,现在它工作正常。但是我应该在哪里发布vc?这是 QuizViewController.h:

#import <UIKit/UIKit.h>

@interface QuizViewController : UIViewController {
    IBOutlet UILabel *questionLabel;
    IBOutlet UIButton *button1;
    IBOutlet UIButton *button2;
    IBOutlet UIButton *button3;

    int currentQuestionIndex;
    int corrects;
    NSMutableArray *questions;
    NSMutableArray *answers;
    NSMutableArray *correctAnswers;
}

- (IBAction)foo:(id)sender;

@end

...和 ​​QuizViewController.m:

#import "QuizViewController.h"

@implementation QuizViewController

- (id)init {
    NSLog(@"QuizViewController init");
    [super initWithNibName:@"QuizViewController" bundle:nil];

    questions = [[NSMutableArray alloc] init];
    answers = [[NSMutableArray alloc] init];
    correctAnswers = [[NSMutableArray alloc] init];

    [questions addObject:@"Vad betyder det engelska ordet \"though\"?"];
    [answers addObject:@"Tuff"];
    [answers addObject:@"Dock"];
    [answers addObject:@"Tanke"];
    [correctAnswers addObject:@"Dock"];

    [questions addObject:@"Vad hette frontpersonen i Popbandet Queen?"];
    [answers addObject:@"Pierre Bouviere"];
    [answers addObject:@"Freddie Mercury"];
    [answers addObject:@"Stevie Wonder"];
    [correctAnswers addObject:@"Freddie Mercury"];

    return self;
}


- (IBAction)foo:(id)sender {
    NSLog(@"foo");
}

- (void)loadView {
    NSLog(@"QuizViewController loadView");
    [questionLabel setText:[questions objectAtIndex:currentQuestionIndex]];
    [button1 setTitle:[answers objectAtIndex:currentQuestionIndex] forState:UIControlStateNormal];
    [button2 setTitle:[answers objectAtIndex:currentQuestionIndex + 1] forState:UIControlStateNormal];
    [button3 setTitle:[answers objectAtIndex:currentQuestionIndex + 2] forState:UIControlStateNormal];

    [super loadView];
}

- (void)viewDidLoad {
    NSLog(@"QuizViewController viewDidLoad");
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

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

@end

【问题讨论】:

    标签: iphone release


    【解决方案1】:

    您应该创建一个实例变量来保存 VC。释放它时丢失它的原因是窗口只保留视图而不是控制器。

    【讨论】:

      【解决方案2】:

      我想我可以像我听到的那样释放 vc,因为 window 会保留它...

      请注意,您正在将与视图控制器 ([vc view]) 关联的视图添加到您的 UIWindow。该对象将被保留,而不是您的控制器。

      您可以通过在您的FirstAppDelegate 中定义一个变量来将控制器存储在那里并在FirstAppDelegate dealloc 中释放它来解决此问题。

       @interface FirstAppDelegate
       .....
       @property (nonatomic, retain) QuizViewController* controller;
       .....
       @end
      
       @implementation FirstAppDelegate
      
       @synthesize window;
       @synthesize controller;
      
       - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {
          self.controller = [[QuizViewController alloc] init] autorelease];
          [window addSubview:[vc view]];
          [window makeKeyAndVisible];
      
          return YES;
      }
      
      - (void)dealloc {
         ....
         [controller release]; controller = nil;
         ....
      }
      

      【讨论】:

        【解决方案3】:

        视图/窗口确实保留了它们的子视图,视图控制器保留了它们的视图,但视图不保留了它们的控制器。这是一种“单向”的关系,明确的has-a。这对于防止保留循环也很方便。

        您可能希望将控制器保存在分配/初始化它的类中的 ivar 中,然后在 dealloc 或从屏幕拉取视图时释放它。

        视图控制器通常会被其他视图控制器保留,即当您将它们推送到导航堆栈或将它们放入选项卡时。​​p>

        【讨论】:

          【解决方案4】:

          如果您不介意放弃对 iOS 3.0/3.1/3.2 的支持,可以使用 UIWindow.rootViewController 属性:

          - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions (NSDictionary *)launchOptions {
              UIViewController *vc = [[[QuizViewController alloc] init] autorelease];
              window.rootViewController = vc;
              [window makeKeyAndVisible];
          
              return YES;
          }
          

          【讨论】:

            猜你喜欢
            • 2012-08-20
            • 1970-01-01
            • 1970-01-01
            • 2012-07-06
            • 2013-06-08
            • 1970-01-01
            • 2014-07-30
            • 2023-03-15
            • 1970-01-01
            相关资源
            最近更新 更多