【问题标题】:NSString placeholder for class name类名的 NSString 占位符
【发布时间】:2014-07-16 10:19:29
【问题描述】:

如何使用占位符来表示班级名称?我有基于传入参数按名称引用其他类的方法。在下面的粗略示例中,我需要能够仅根据名称加载三个 ViewController 之一(而不是 ViewController 数组,因为这只是一个示例)。

-(void)loadViewController:(int)vcNumberToLoad
{
    NSString *vcOne = @"firstViewControllerName";
    NSString *vcTwo = @"secondViewControllerName";
    NSString *vcThree = @"thirdViewControllerName";

    NSArray *vcArray = [NSArray arrayWithObjects:vcOne, vcTwo, vcThree, nil];

    NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad];

    UIViewController |VALUE OF nameOfVCToLoad| = [[UIViewController alloc] init]; // What is the code to get the value of nameOfVCToLoad to be used as the instance name of the UIVC class
    [self.navigationController pushViewController:|VALUE OF nameOfVCToLoad| animated:NO];

}

例如,如果方法使用参数 '1' 运行

NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad]; //this would = secondViewControllerName

UIViewController secondViewControllerName = [[UIViewController alloc] init];
[self.navigationController pushViewController:secondViewControllerName animated:NO];

其他问题似乎暗示 [NSClassFromString:nameOfVCToLoad] 可能符合我的需要,如果是的话,如何?

【问题讨论】:

  • 为什么要关心local变量名?
  • 这纯粹是一个例子,试图说明我想知道如何使用 NSString 作为类的实际名称的占位符的主要观点。
  • 变量名用于在开发会话期间使代码可读。在 runtime 中,处理器不会使用 var 的名称,它仅在 addresses 中起作用。因此,您在 runtime 期间动态定义变量名的问题在实践中没有太大意义。
  • 在我的示例中,可能有 100 个动态创建的按钮都使用相同的选择器方法。该方法只能真正获取按钮标签,然后该标签可以用于加载相关的ViewController。我的想法是标签可以对应于任何数组的索引,索引处的项目将是项目名称。这个项目名称可以用于多种事物,其中之一是要加载的相应 ViewController 的名称。我认为在这种情况下可以使用占位符。

标签: ios objective-c cocoa-touch uiviewcontroller nsstring


【解决方案1】:

你对对象感到困惑。你正在寻找这个

NSClassFromString(vcOne) 将帮助您进行动态类选择

isKindOfClass 将帮助您确定该类是否为给定类

-(void)loadViewController:(int)vcNumberToLoad
{
    NSString *vcOne = @"firstViewControllerName";
    NSString *vcTwo = @"secondViewControllerName";
    NSString *vcThree = @"thirdViewControllerName";


    firstViewControllerName *fvc = nil;
    secondViewControllerName *svc = nil;
    thirdViewControllerName *tvc = nil;


    NSArray *vcArray = [NSArray arrayWithObjects:vcOne, vcTwo, vcThree, nil];

    NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad];


    UIViewController *aLoadedViewController = [[NSClassFromString(nameOfVCToLoad) alloc] init];

    if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcOne)]]) {

        fvc = aLoadedViewController;

    }
    else if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcTwo)]]) {

        svc = aLoadedViewController;

    }
    else if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcThree)]]) {

        tvc = aLoadedViewController;

    }

    [self.navigationController pushViewController:aLoadedViewController animated:NO];

}

【讨论】:

  • 有点过于复杂的做法......无论如何+1。
  • 如果有很多视图控制器怎么办?您需要编写一组很长且不是很动态的 if 语句吗?
  • 如果您想找出并提供有关该特定视图控制器的一些额外数据,那么您必须这样做。否则不需要它。
  • 像 fvc.someproperty = somevalues;那么你需要 if 循环来区分它。否则只需使用 aLoadedViewController。您自己的每个视图控制器都是继承的 UIViewcontroller 。所以导航控制器需要一个视图控制器。就是这样。
  • 这可能是我在这里寻找的最接近的。我将针对我的实际问题发布一个更具体的问题,看看我是否需要重新考虑我的方法。谢谢。
【解决方案2】:

Objective-c 具有Class 类型,作为NSObject 的一部分存在。

更准确地说是:

-(void)loadViewController:(int)vcNumberToLoad {
     Class vcOne = [FirstViewControllerName class];
     Class vcTwo = [SecondViewControllerName class];
     Class vcThree = [ThirdViewControllerName class];

     Class viewControllerClass;
     // switch between classes

     UIViewController *viewControllerToPush = [[viewControllerClass alloc] init];
     // push UIViewController
}

这样做的好处在于编译时的类型检查

【讨论】:

    猜你喜欢
    • 2013-10-19
    • 2012-07-04
    • 2019-03-25
    • 2019-07-25
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    相关资源
    最近更新 更多