освобождение объектов? - PullRequest
1 голос
/ 29 июня 2011

Я действительно новичок в программировании 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 так, как слышу, так как окно сохранит его (?), Но оно выдало ошибку:

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

Ответы [ 4 ]

1 голос
/ 29 июня 2011

Вы должны создать переменную экземпляра для хранения VC.Причина, по которой вы теряете его, когда отпускаете его, заключается в том, что окно сохраняет только вид, а не контроллер.

1 голос
/ 29 июня 2011

Я думал, что смогу выпустить vc, как слышу, так как окно сохранит его ...

Обратите внимание, что вы добавляете представление, связанное с контроллером представления ([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;
   ....
}
0 голосов
/ 29 июня 2011

Если вы не против отказаться от поддержки 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;
}
0 голосов
/ 29 июня 2011

Представления / окна сохраняют свои дочерние представления, контроллеры представления сохраняют свои представления, но представления не сохраняют свои контроллеры. Это «односторонние» отношения, четкие has-a . Это также пригодится для предотвращения сохранения циклов.

Вы, вероятно, хотите сохранить контроллер в иваре в классе, который вы выделяете / инициализируете, и освобождаете его в dealloc или при извлечении вида с экрана.

Контроллеры представления часто сохраняются другими контроллерами представления, т. Е. Когда вы помещаете их в стек навигации или помещаете их во вкладки.

...