1

EDITED

This is a very common problem I am facing during coding, please take a look at it.

- (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

There are two conclusions to above written code.

1.If I use loadView method. It calls out the view controller's view and allocate memory just to IBOutlets and doesn't do for other self.recentPlanViewController Instance variables.

2.If I skip second line of code, it doesn't allocate memory to any IVR even after using it as rootVC.

Please guide me, what is the memory management concept I'm violating!

Thanks

4

3 に答える 3

2

いくつかの問題があります:

  • あなたはloadView直接電話しています
  • ビューコントローラーのビューを表示していません

loadView

ドキュメントには次のように記載されています。

ストーリーボードまたは nib ファイルでビューを定義できない場合は、loadView メソッドをオーバーライドして、ビュー階層を手動でインスタンス化し、それをビュー プロパティに割り当てます。

と:

このメソッドを直接呼び出してはいけません [loadView]。ビュー コントローラーは、ビュー プロパティが要求されたときにこのメソッドを呼び出しますが、現在は nil です。このメソッドは、ビューをロードまたは作成し、それをビュー プロパティに割り当てます。

これは何を意味するのでしょうか?

ビュー コントローラーにビューを提供するには、次の 3 つの方法があります。

  • ストーリーボードの使用
  • ニブの使用
  • プログラム的に

つまり、s について話しているのでIBOutlet、3 番目の方法は除外する必要があります。

いつIBOutlet「準備完了」ですか?

入力viewDidLoad:

このメソッドは、View Controller がそのビュー階層をメモリにロードした後に呼び出されます。このメソッドは、ビュー階層が nib ファイルからロードされたか、loadView メソッドでプログラムによって作成されたかに関係なく呼び出されます。

このメソッドが呼び出されると、IBOutletの準備が整い、安全にアクセスできます。

ビューを表示しています

ビューコントローラーの階層が何であるかはわかりませんが、おそらく再利用するのではnavigationControllerなく、再割り当てしています。

そのView Controllerが別のView Controllerからプッシュされた場合、これを行う必要があります:

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

navigationController階層を管理しているを再利用する(再割り当てしない) ためです。

だから、問題は次のとおりです。どのように表示していLandingViewControllerますか?

于 2012-10-22T07:36:09.327 に答える
1

問題は、loadView自動的に呼び出されることです。自分で呼び出すべきではありません。呼び出されるUIViewControllerには、画面に表示される必要があります。現時点であなたが持っているのはあなたへのポインターでrecentPlanViewControllerあり、それだけです。loadViewviewDidLoad、を呼び出すには、次のviewWillAppearようにする必要があります。

[self pushViewController:self.recentPlanViewController];

が実際に画面に表示さIBOutletsれるまでは、信頼しないでください。最初にいくつかのデフォルト値UIViewControllerを持たせたい場合は、それらをメソッドに渡し、ivar として保存してから、たとえば に設定する必要があります。IBOutletsinitviewDidLoad

編集:

これには問題があるかもしれません:

self.navigationController = [[UINavigationController alloc] initWithRootViewController:self.recentPlanViewController ];

独自のナビゲーションコントローラーを再初期化しているためです。

編集2:

UIViewController既に作業中の があると仮定してnew を表示したいだけの場合は、次のUINavigationControllerことができます。

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

持っていない場合は、次のself.navigationControllerことができます。

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

}];
于 2012-10-22T06:51:52.480 に答える
0

回避 策は、View Controller 自体で iVar を関連付けるか使用することです。

于 2012-10-23T16:09:00.583 に答える