【问题标题】:objectAtIndex:indexPath.row method always causes exception in IOSobjectAtIndex:indexPath.row 方法总是在 IOS 中导致异常
【发布时间】:2012-11-14 14:22:28
【问题描述】:

嗨,当我使用 objectAtInded 方法从数组中检索 NSString 时,我似乎总是遇到异常。我正在从“PropertyList.plist”文件中的字典中读取数据。我的代码是

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"PropertyList"
                                                     ofType:@"plist"];
    names = [[NSDictionary alloc]
             initWithContentsOfFile:path];

    keys = [[[names allKeys] sortedArrayUsingSelector:
             @selector(compare:)] retain];
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger section = [indexPath section];
    NSUInteger row = [indexPath row];

    NSString *key  = [keys objectAtIndex:section];
    NSArray *nameSection = [names objectForKey:key];
    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
    if(cell == nil)
    {
        cell = [[[UITableViewCell alloc]
                 initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SectionsTableIdentifier] autorelease];
    }
    cell.textLabel.text = [nameSection objectAtIndex:row];
    return cell;
}

异常发生在方法“cellForRowAtIndexPath”行中

cell.textLabel.text = [nameSection objectAtIndex:row];

错误信息是

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSCFDictionary objectAtIndex:]:无法识别的选择器发送到实例 0x6832440

plist 文件是

我在哪里使用“[nameSection objectAtIndex:row];”语句的类型它总是得到异常。

【问题讨论】:

  • 因为这里编译器将 nameSection 作为 NSDictionary 而不是 NSArray。并且在字典对象上调用 objectAtIndex: 会引发异常。您必须交叉检查 PropertyList plist 的结构。
  • 如何将nameSection的值作为一个数组?我试着做#Jasmeet Singh 所说的 NSMutableArray nameSection = (NSMutableArray)[names objectForKey:key];但它显示了同样的异常!
  • 我是说要交叉检查您的 plist 结构。 [names objectForKey:key] 函数返回的是 NSDictionary 对象而不是 NSArray。

标签: ios xcode uitableview plist


【解决方案1】:

原因可能如下

  1. [命名 objectForKey:key];。该语句可以为输出提供 NSMutableDictionary 类型,并且您从中获取 NSArray。或者

  2. 如果是数组,则使用以下代码获取 nameSection

       NSMutableArray *nameSection = (NSMutableArray*)[names objectForKey:key];
       // using (NSMutableArray*) before the code is for external typecasting to tell the compiler that the output is of NSMutableArray type.
    

希望这会有所帮助。

编辑:-

使用下面的方法从 plist 文件中获取你的字典

        -(NSMutableDictionary *) GetDictDataFromPlistFile:(NSString *) fileName
       {
             NSError *error;
             NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //1
             NSString *documentsDirectory = [paths objectAtIndex:0]; //2
             NSString *path = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",fileName]]; //3

              NSFileManager *fileManager = [NSFileManager defaultManager];

            if (![fileManager fileExistsAtPath: path]) //4
            {
                   NSString *bundle = [[NSBundle mainBundle] pathForResource:fileName ofType:@"plist"]; //5
                  [fileManager copyItemAtPath:bundle toPath: path error:&error]; //6
             }

              NSMutableDictionary *dictData =   [[NSMutableDictionary alloc] initWithContentsOfFile:path];

               return dictData;
        }

【讨论】:

  • 将代码更改为 NSMutableArray nameSection = (NSMutableArray)[names objectForKey:key];但还是一样的例外!
  • 为此我们应该知道您的 plist 文件的结构。 NSLog(@"%@", nameSection);在 NSArray *nameSection = [names objectForKey:key]; 行之后使用它看看它打印了什么。
【解决方案2】:

这里,name 只包含root 的一个键。 name 需要的是键 Root 的值。 请重试!

【讨论】:

    【解决方案3】:

    就像@scorpiozj 说的'names' 只包含'Root' 的键。所以我所做的我知道这不是一个很好的方法。我确信还有其他方法。我把'viewDidLoad'方法改成了这个,

     - (void)viewDidLoad
    {
        [super viewDidLoad];
        NSString *path = [[NSBundle mainBundle] pathForResource:@"PropertyList"
                                                         ofType:@"plist"];
        names = [[NSDictionary alloc]
                 initWithContentsOfFile:path];
        keys = [names allKeys];
        NSString *key = [keys objectAtIndex:0];
        names = [names objectForKey:key];
        keys = [[[names allKeys] sortedArrayUsingSelector:@selector(compare:)] retain];
        NSLog(@"keys = %@  names = %@",keys,names);
    }
    

    有效!任何想法如何做得更好都将不胜感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-23
      • 2012-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多