EDITED
这是我在编码过程中遇到的一个非常常见的问题,请看一下。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
// Adding Landing screen landscape on mainwindow
self.landingViewController = [[LandingViewController alloc] initWithNibName:@"LandingViewController" bundle:nil];
[self.window addSubview:self.landingViewController.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
#import <UIKit/UIKit.h>
@class RecentPlanViewController;
@class ChevronViewController;
@interface LandingViewController : UIViewController
{
UINavigationController *navigationController;
// custom view controllers
RecentPlanViewController *recentPlanViewController;
ChevronViewController *chevronViewController;
}
- (void)popView:(NSNotification *)notification;
@property (nonatomic,retain) UINavigationController *navigationController;
@property (nonatomic,retain) RecentPlanViewController *recentPlanViewController;
@property (nonatomic,retain) ChevronViewController *chevronViewController;
@end
self.recentPlanViewController = [[RecentPlanViewController alloc] initWithNibName:@"RecentPlanViewController" bundle:nil];
[self.recentPlanViewController loadView]; // if I skip this : Memory to recentPlanViewController's IVs not allocated.
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.recentPlanViewController ];
#import <UIKit/UIKit.h>
@class RecentPlanCell;
@interface RecentPlanViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *recentPlanTableView; // Main recent TableView
RecentPlanCell *recentPlanCell;
IBOutlet UIButton *createPlanButton;
IBOutlet UIButton *viewAllPlanButton;
BOOL isViewingAllPlans; // Yes if view all plan pressed
}
@property (nonatomic,retain) RecentPlanCell *recentPlanCell;
@property (nonatomic,retain) IBOutlet UIButton *createPlanButton;
@property (nonatomic,retain) IBOutlet UIButton *viewAllPlanButton;
@end
以上编写的代码有两个结论。
1.如果我使用loadView方法。它调用视图控制器的视图并仅为IBOutlets分配内存,而不用于其他self.recentPlanViewController
实例变量。
2.如果我跳过第二行代码,即使将其用作rootVC,它也不会为任何IVR分配内存。
请指导我,我违反的内存管理概念是什么!
由于
答案 0 :(得分:2)
有一些问题:
loadView
loadView
如果无法在故事板或nib文件中定义视图,请覆盖loadView方法以手动实例化视图层次结构并将其分配给视图属性。
和
你永远不应该直接调用这个方法[loadView]。视图控制器在请求其view属性但当前为nil时调用此方法。此方法加载或创建视图并将其分配给视图属性。
有三种方法可以为视图控制器提供视图:
所以,既然你在谈论IBOutlet
,那么必须排除第三种方式。
IBOutlet
'何时'准备好'?输入viewDidLoad
:
在视图控制器将其视图层次结构加载到内存后调用此方法。无论视图层次结构是从nib文件加载还是在loadView方法中以编程方式创建,都会调用此方法。
调用此方法后,您的IBOutlet
已准备就绪,您可以安全地访问它们。
我不知道您的视图控制器的层次结构是什么,但您可能正在重新分配navigationController
而不是重复使用它。
如果从另一个视图控制器推送该视图控制器,则应执行此操作:
[self.navigationController pushViewController:self.recentPlanViewController animated:YES];
为了重用管理层次结构的navigationController
(而不是重新分配)。
所以,问题是:你如何展示LandingViewController
?
答案 1 :(得分:1)
问题是,loadView
是自动调用的,你不应该自己调用它。要调用它,您的UIViewController
必须出现在屏幕上。你现在所拥有的是指向你recentPlanViewController
的指针,就是这样。要调用loadView
,viewDidLoad
,viewWillAppear
,您需要执行以下操作:
[self pushViewController:self.recentPlanViewController];
在IBOutlets
实际出现在屏幕上之前,您不应该依赖UIViewController
。如果您希望IBOutlets
在开头有一些默认值,则应在init
方法上传递它们,将它们保存为ivars,然后在viewDidLoad
中设置它们,例如。
修改强>
这可能有问题:
self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.recentPlanViewController ];
因为您正在重新初始化您自己的navigationController。
编辑2:
如果您只是想显示新的UIViewController
,假设您已经有效UINavigationController
,则可以执行以下操作:
[self.navigationController pushViewController:self.recentPlanViewController animated:YES];
如果您没有self.navigationController
,则可以:
[self presentViewController:self.recentPlanViewController animated:YES completion:^{
}];
答案 2 :(得分:0)
解决方法是: 在视图控制器本身中关联或使用iVars。