objectForKey在字典上返回nil

时间:2011-09-28 10:12:55

标签: objective-c

我正在为iPad创建一个配方管理器应用程序。我正在使用拆分视图模板,该模板从以这种方式构造的plist加载配方的数据。左侧的表格视图完美无缺。它从plist加载数据。问题是细节视图。正如您所看到的,我在DetailViewController.m文件中插入了一条NSLog行,因为我传递给文本字段的每个字符串都是nil。奇怪的是,当我尝试从RootViewController.m使用NSLog时:     NSLog(@“%@”,[detailViewController.ricetta allKeys]) 它奏效了。

有什么建议吗?

我尝试尽可能多地发布行来解释问题。

<plist version="1.0">
    <array>
        <dict>
            <key>name</key>
            <string>Risotto alla zucca</string>
            <key>ingredients</key>
            <string></string>
            <key>description</key>
            <string></string>
            <key>photo</key>
            <string></string>
        </dict>
        <dict>
            <key>name</key>
            <string>Semi di zucca al forno</string>
            <key>ingredients</key>
            <string></string>
            <key>description</key>
            <string></string>
            <key>photo</key>
            <string></string>
        </dict>
        <dict>
            <key>name</key>
            <string>Risotto ai funghi</string>
            <key>ingredients</key>
            <string></string>
            <key>description</key>
            <string></string>
            <key>photo</key>
            <string></string>
        </dict>
    </array>
</plist>

RootViewController.h

#import <UIKit/UIKit.h>

#import "RecipeConstants.h"

@class DetailViewController;

@interface RootViewController : UITableViewController {
    NSMutableArray *ricette;
}

@property (nonatomic, retain) NSMutableArray *ricette;

@property (nonatomic, retain) IBOutlet DetailViewController *detailViewController;

@end

RootViewController.m

...
@synthesize ricette;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.clearsSelectionOnViewWillAppear = NO;
    self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);

    NSString *path = [[NSBundle mainBundle] pathForResource:@"RicetteArray" ofType:@"plist"];
    NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
    self.ricette = tmpArray;
    [tmpArray release];
}
...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.ricette count];

}
    // Configure the cell.

    cell.textLabel.text = [[self.ricette objectAtIndex:indexPath.row] objectForKey:NAME_KEY];
    return cell;
}
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    detailViewController.ricetta = [self.ricette objectAtIndex:indexPath.row];    
}
...
- (void)dealloc
{
    [detailViewController release];

    [ricette release];

    [super dealloc];
}
@end

DetailViewController.h

#import <UIKit/UIKit.h>

#import "RecipeConstants.h"

@interface DetailViewController : UIViewController <UIPopoverControllerDelegate, UISplitViewControllerDelegate> {

    IBOutlet UILabel *lblTitolo;
    IBOutlet UITextView *ingredientiTxtView;
    IBOutlet UITextView *descrizioneTxtView;
    IBOutlet UIImageView *fotoImgView;

    NSDictionary *ricetta;
}

@property (nonatomic, retain) IBOutlet UILabel *lblTitolo;
@property (nonatomic, retain) IBOutlet UITextView *ingredientiTxtView;
@property (nonatomic, retain) IBOutlet UITextView *descrizioneTxtView;
@property (nonatomic, retain) IBOutlet UIImageView *fotoImgView;
@property (nonatomic, retain) NSDictionary *ricetta;

@property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
@property (nonatomic, retain) id detailItem;

@end

DetailViewController.m

@synthesize lblTitolo, ingredientiTxtView, descrizioneTxtView, fotoImgView, ricetta;
...
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    lblTitolo.text = [ricetta objectForKey:NAME_KEY];
    ingredientiTxtView.text = [ricetta objectForKey:INGREDIENTS_KEY];
    descrizioneTxtView.text = [ricetta objectForKey:DESCRIPTION_KEY];
    UIImage *img = [UIImage imageNamed:PHOTO_KEY];
    fotoImgView.image = img;

    NSLog(@"%@", [ricetta allKeys]);
}
...
- (void)dealloc
{
    [_myPopoverController release];
    [_toolbar release];
    [_detailItem release];

    [lblTitolo release];
    [ingredientiTxtView release];
    [descrizioneTxtView release];
    [fotoImgView release];
    [ricetta release];

    [super dealloc];
}

@end

更新: 实际上在DetailViewController.m中我有这个方法:

- (void)updateRicetta {
    lblTitolo.text = [ricetta objectForKey:NAME_KEY];

    NSString *myIngredients = [ricetta objectForKey:INGREDIENTS_KEY];
    myIngredients = [myIngredients stringByReplacingOccurrencesOfString:@", " withString:@"\n"];
    ingredientiTxtView.text = myIngredients;

    NSString *myDescription = [ricetta objectForKey:DESCRIPTION_KEY];
    myDescription = [myDescription stringByReplacingOccurrencesOfString:@". " withString:@"\n"];
    descrizioneTxtView.text = myDescription;

    NSString *nomeImmagine = [NSString stringWithFormat:@"%@.jpg", [ricetta objectForKey:PHOTO_KEY]];
    [self.fotoImgView setImage:[UIImage imageNamed:nomeImmagine]];
}

中的RootViewController.m调用
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
使用

[detailViewController updateRicetta];

我有以下两个警告:

'DetailViewController' may not respond to '-updateRicetta'
Instance method '-updateRicetta not found (return type defaults to 'id')

另一个问题是,只有当我点击不在应用加载的单元格时,详细视图才会更新。

1 个答案:

答案 0 :(得分:1)

我很高兴在这方面做错了,但是在我看来tableView:didSelectRowAtIndexPath:你在DetailViewController中设置了食谱(ricetta?)但我看不到任何指示时告诉DetailViewController显示新食谱。

您有代码更新DetailViewController viewWillAppear:animated:,但这只会在视图出现时发生 - 如果您的视图已经显示,则此方法将无法执行。

我建议您在DetailViewController中创建一个名为updateRicetta的方法,该方法如下所示:

- (void)updateRicetta {
    lblTitolo.text = [ricetta objectForKey:NAME_KEY];
    ingredientiTxtView.text = [ricetta objectForKey:INGREDIENTS_KEY];
    descrizioneTxtView.text = [ricetta objectForKey:DESCRIPTION_KEY];
    UIImage *img = [UIImage imageNamed:PHOTO_KEY];
    fotoImgView.image = img;
}

然后你可以从tableView中调用它:didSelectRowAtIndexPath: -

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    detailViewController.ricetta = [self.ricette objectAtIndex:indexPath.row];
    [detailViewController updateRicetta];
}

关于返回nil:,我的猜测是,当调用viewWillAppear:animated:时,您尚未选择条目,因此尚未在DetailViewController中设置ricetta。