2011-06-28 109 views
1

我真的很新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 

回答

1

我以爲我可以釋放VC像我這樣做,因爲聽到窗口將保留它...

請注意,您將與視圖控制器相關的視圖([vc view])添加到您的UIWindow。該對象將被保留,而不是您的控制器。

您可以通過在您的FirstAppDelegate中定義一個變量來存儲控制器並將其釋放到FirstAppDelegatedealloc中來解決此問題。

@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

您應該創建一個實例變量來容納VC。釋放它時丟失它的原因是窗口只保留視圖而不是控制器。

0

視圖/窗口保留其子視圖,視圖控制器保留其視圖,但視圖不保留其控制器。這是一種「單向」關係,明確的有一個。這也可以防止保留週期。

您可能想要將控制器保存在您分配/初始化的類中的ivar中,然後在dealloc或您從屏幕拉取視圖時將其釋放。

視圖控制器通常會被其他視圖控制器保留下來,即當您將它們推到導航堆棧上或放入選項卡時。

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; 
}