【问题标题】:Local Decleration Hides Instance Variable - setting up ViewNavigation Controller本地声明隐藏实例变量 - 设置视图导航控制器
【发布时间】:2013-06-02 15:50:54
【问题描述】:

我正在将一个只是 TabViewContoller 的简单应用程序转换为需要通过 Navagation 控制器推送多个视图的应用程序。以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Create Start view controller.
    UITabBarController *rootController = [[UITabBarController alloc] init];
    UINavigationController *startController = [[UINavigationController alloc] initWithRootViewController:rootController];

    // Similarly create for TabBarController, ToDoController and any others over time ...
    UIViewController *ToDoViewController = [[UIViewController alloc] initWithNibName:@"ToDoViewController" bundle:nil];

    // Create an array of view controllers.
    NSArray* controllers = [NSArray arrayWithObjects:startController, ToDoViewController, nil];

    // Create our tab bar controller.
    self.rootController = [[UITabBarController alloc] init];

    // Set the view controllers of the tab bar controller.
    self.rootController.viewControllers = controllers;

    // Add the tab bar controller to the window.
    [self.window addSubview:self.rootController.view];

    [self.window makeKeyAndVisible];

    return YES;
}

运行时给我两个警告和崩溃。警告位于 UINavigationController 行和 NSArray 行上。在这两种情况下,我都会收到以下信息:

rootContoller 的局部声明隐藏实例变量。

这是我的头文件:

    #import <UIKit/UIKit.h>


@interface Wasted_TimeAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UITabBarController *rootController;
    UINavigationController *startController;

}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *rootController;
@property (nonatomic, retain) IBOutlet UINavigationController *startController;
@end

我确信这与我希望 UITabBarContoller 成为我在堆栈中的第一个视图控制器这一事实有关。有关设置此行为的正确方法的任何建议?

【问题讨论】:

  • 在您当前的实现中,您拥有由 UINavigationController 组成的 UITabBarController,其中包含一个 UITabBarController 内部。

标签: objective-c variables uinavigationcontroller instance


【解决方案1】:

编译器抱怨您有一个与实例变量同名的局部变量。您似乎在rootViewControllerstartController 上也有一个IBOutlet。你真的需要那个吗?

使用 Objective C 的自动属性合成,您可以删除头文件中的实例变量。这将消除您的警告。

#import <UIKit/UIKit.h>
@interface Wasted_TimeAppDelegate : NSObject <UIApplicationDelegate> {}
@property (nonatomic, retain) IBOutlet UIWindow *window;

// Removed IBOutlet since the view controller is created in code
@property (nonatomic, retain) UITabBarController *rootController;
@property (nonatomic, retain) UINavigationController *startController;
@end

然后更改您的方法以使用属性

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Create Start view controller.
    // PS: Using properties
    self.rootController = [[UITabBarController alloc] init];
    self.startController = [[UINavigationController alloc] initWithRootViewController:rootController];

    // Similarly create for TabBarController, ToDoController and any others over time ...
    UIViewController *ToDoViewController = [[UIViewController alloc] initWithNibName:@"ToDoViewController" bundle:nil];

    // Create an array of view controllers.
    NSArray* controllers = [NSArray arrayWithObjects:startController, ToDoViewController, nil];

    // Create our tab bar controller.
    self.rootController = [[UITabBarController alloc] init];

    // Set the view controllers of the tab bar controller.
    self.rootController.viewControllers = controllers;

    // Add the tab bar controller to the window.
    [self.window addSubview:self.rootController.view];

    [self.window makeKeyAndVisible];

    return YES;
}

【讨论】:

    【解决方案2】:

    问题是您有一个名为rootController 的实例变量。然后在您发布的代码中,您还有一个名为rootController 的局部变量。警告只是告诉您局部变量rootController 隐藏了实例变量rootController。换句话说,由于局部变量,您无法直接访问该代码块中的实例变量。

    这可能是也可能不是问题。这取决于你需要什么。

    有两种解决方案:

    1) 将局部变量重命名为不同的名称,这样它就不会隐藏实例变量。

    2) 使用现代的 Objective-C 编译器特性。摆脱用于属性的实例变量。还要摆脱对@synthesize 的任何显式调用。您只需要@property 行。无需同时声明关联的实例变量。

    在这种情况下,选项 2 是更好的选择。然后对rootController 的任何引用都将指向局部变量,对属性的任何引用都将使用self.rootController 完成。您永远不需要直接访问实例变量(现在将其命名为 _rootController)。

    【讨论】:

    • 在为此苦苦挣扎了一段时间后,我最终重构了我的应用程序以使用原始基于 XIB 的应用程序的 Storeboard。在重组期间,我删除了导致此问题的结构。 (这基本上让我走上了#2 的道路)。
    猜你喜欢
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    相关资源
    最近更新 更多