调用numberOfRowsInSection时,忘记了TableView初始值设定项中的变量集

时间:2012-10-01 14:30:22

标签: ios cocoa-touch

我正在使用带有ARC的Xcode 4.5创建一个UITableViewController类,我想用NSDictionary初始化它。在它的初始化程序中,创建的[resourcesAsDictionary count]返回一些正确的值,但稍后当我在主视图中按下一个按钮时,表是根据我初始化类的NSDictionary的条目数构建的,NSDictionary始终为空,[resourcesAsDictionary count]返回0。 我认为这与ARC有关吗?如果我把它关掉,我可以保留那个变量吗?但是必须有一种方法可以获得这个与ARC?) 相关代码:

编辑:我已根据收到的帮助更改了代码 edit2:由于我能够缩小问题的范围并且这有点令人困惑,而且阅读起来很多,我创建了一个新主题:ViewController class creates new instance when creating view, but it should use an existing one
编辑3:问题在已经链接的线程中解决了,这就是问题。

ViewController.h:

#import <UIKit/UIKit.h>
#import <Foundation/NSJSONSerialization.h>
#import <Foundation/NSXMLParser.h>
#import "ResourcesTableViewController.h"

@interface ViewController : UIViewController <UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource> {
// Note: this <UITableViewDelegate, UITableViewDataSource> is NOT related to the TableViewController. My ViewController has another TableView.
NSDictionary *parsedResponseAsDictionary;
ResourcesTableViewController *resourceTableViewController;
...
}
...

ViewController.m中的某个地方:

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    parsedResponseAsDictionary = [[NSDictionary alloc] init];
}
...
-   (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)_bodyData {
    parsedResponseAsDictionary = [NSJSONSerialization JSONObjectWithData:bodyData options:NSJSONWritingPrettyPrinted error:&err];
    ... // putting found keys as entries in an array foundResources
    if ([foundResources count] > 0) {
        resourceTableViewController = [[ResourcesTableViewController alloc] initWithStyle:UITableViewStylePlain];
        [resourceTableViewController setResourcesAsDictionary:parsedResponseAsDictionary];
        NSLog(@"Delivered %i entries.",[[resourceTableViewController resourcesAsDictionary] count]);
        // TableView can be built: enable "Show Resources" button
        [_showResourcesButton setAlpha:1];
        [_showResourcesButton setEnabled:YES];
    }
}
...
// Output:
// REST Analyzer[1259:c07] Delivered 8 entries.
// REST Analyzer[1259:c07] viewWillAppear: (null)
// REST Analyzer[1259:c07] Now: 0 entries.

ResourcesTableViewController.h:

#import <UIKit/UIKit.h>

@interface ResourcesTableViewController : UITableViewController {
}

@property (nonatomic, strong) NSDictionary *resourcesAsDictionary;

@end

ResourcesTableViewController.m:

#import "ResourcesTableViewController.h"

@implementation ResourcesTableViewController

// - (id)initWithDictionary:(NSDictionary*)dic {
//    if (self = [super init])
//        resourcesAsDictionary = [[NSDictionary alloc] initWithDictionary:dic];
//    NSLog(@"resource table created with %i entries.",[resourcesAsDictionary count]);
//    return self;
// }

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"viewWillAppear: %@", self.resourcesAsDictionary);
    // (null) is returned here.
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"Now: %i entries.",[self.resourcesAsDictionary count]);
    return [self.resourcesAsDictionary count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
                                      reuseIdentifier:CellIdentifier];
    }

    cell.textLabel.text = @"Cell";
    cell.detailTextLabel.text = @"Description";

    return cell;
}

1 个答案:

答案 0 :(得分:1)

我会以两种方式改变这一点......

删除iVar for resourcesAsDictionary并将其设置为属性。

@property (nonatomic, strong) NSDictionary *resourcesAsDictionary;

然后我将通过删除init方法并使用此属性来更改初始化。

在推送到这个控制器的viewController中(即你调用initWithDictionary的地方)......

而不是initWithDictionary有......

ResourcesTableViewController *tvc = [[ResourcesTableViewController alloc] initWithStyle:<whicheverstyleyouneed>];

然后设置属性......

tvc.resourcesAsDictionary = mySourceDictionary;

然后推TVC ......

[self.navigationController pushViewController:tic animated:YES];

...或者你将它推到屏幕上。

最后,您需要将numberOfRows ...代码更改为...

return [self.resourcesAsDictionary count];

这将是我的方法,这意味着您不必覆盖UITableViewController类的init。

通过拥有强大的属性,您确保它将在拥有对象的生命周期中保持不变。通过不覆盖init,您可以确保不会错过任何在initWithStyle中调用的代码...

如果这不起作用,那么我只能认为首先创建字典的方式不对。

在 - (void)viewWillAppear ...函数中告诉我...

的输出
NSLog(@"%@", self.resourcesAsDictionary);