1

已编辑

这是我在编码过程中遇到的一个非常常见的问题,请看一下。

- (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分配内存。

请指导我,我违反的内存管理概念是什么!

谢谢

4

3 回答 3

2

有几个问题:

  • loadView直接打电话
  • 你没有显示视图控制器的视图

loadView

文档说:

如果您无法在情节提要或 nib 文件中定义视图,请覆盖 loadView 方法以手动实例化视图层次结构并将其分配给视图属性。

和:

你不应该直接调用这个方法 [loadView]。视图控制器在其视图属性被请求但当前为 nil 时调用此方法。此方法加载或创建视图并将其分配给视图属性。

这是什么意思?

有三种方法可以为视图控制器提供视图:

  • 使用故事板
  • 使用笔尖
  • 以编程方式

所以,既然你在谈论IBOutlets,第三种方式必须被排除在外。

什么时候IBOutlet“准备好”?

输入viewDidLoad

在视图控制器将其视图层次结构加载到内存后调用此方法。无论视图层次结构是从 nib 文件加载还是在 loadView 方法中以编程方式创建,都会调用此方法。

调用此方法后,您IBOutlet的 s 已准备就绪,您可以安全地访问它们。

显示视图

我不知道您的视图控制器层次结构是什么,但您可能正在重新分配navigationController而不是重用它。

如果该视图控制器是从另一个视图控制器推送的,您应该这样做:

[self.navigationController pushViewController:self.recentPlanViewController animated:YES];

为了重用navigationController管理层次结构的那个(而不是重新分配它)。

所以,问题是:你是如何展示的LandingViewController

于 2012-10-22T07:36:09.327 回答
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假设你已经有一个 working UINavigationController,你可以这样做:

  [self.navigationController pushViewController:self.recentPlanViewController animated:YES];

如果你没有,self.navigationController你可以这样做:

[self presentViewController:self.recentPlanViewController animated:YES completion:^{

}];
于 2012-10-22T06:51:52.480 回答
0

解决方法是: 在视图控制器本身中关联或使用 iVar。

于 2012-10-23T16:09:00.583 回答