局部声明隐藏实例变量-设置ViewNavigation控制器



我正在转换一个简单的应用程序,它只是一个tabviewcontroller到一个我需要通过导航控制器推送多个视图。以下代码:

- (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行。在这两种情况下,我得到消息:

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

这是我的头文件:

    #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

我确信它与我想要uitabbarcontroller成为栈中的第一个视图控制器这一事实有关。关于设置此行为的正确方法有什么建议吗?

编译器抱怨你有一个与实例变量同名的局部变量。你似乎在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;
}

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

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

有两个解决方案:

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

2)使用现代Objective-C编译器特性。去掉用于属性的实例变量。同时去掉对@synthesize的显式调用。所有你需要的是@property线。也不需要声明相关的实例变量。

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

最新更新