我是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
答案 0 :(得分:1)
我以为我可以释放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;
....
}
答案 1 :(得分:1)
您应该创建一个实例变量来保存VC。在释放它时丢失它的原因是窗口只保留视图而不是控制器。
答案 2 :(得分:0)
视图/窗口确实保留其子视图,视图控制器保留其视图,但视图不保留其控制器。这是一种“单向”关系,一种清晰的有一个。这对于防止保留周期也很方便。
您可能希望将控制器保存在您分配/初始化的类中的ivar中,并在dealloc
或从屏幕拉出视图时将其释放。
视图控制器通常会被其他视图控制器保留,即将它们推送到导航堆栈时,或将它们放在选项卡中。
答案 3 :(得分:0)
如果您不介意放弃对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;
}