(solve)当调用numberOfRowsInSection时,TableView初始化程序中的变量集被忘记 [英] (solved) Variable set in the TableView initializer is forgotten when numberOfRowsInSection is called

查看:72
本文介绍了(solve)当调用numberOfRowsInSection时,TableView初始化程序中的变量集被忘记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在已经在我的第一篇文章中提出了这个问题,但我不能得到解决。我觉得有点无力再次问这个问题,但我正在写我的学士论文目前(我是新来的XCode和Objective-C),我真的需要做到这一点。高兴帮助我,如果有一些信息缺失,请致电,我很高兴与你沟通。 : - /



我使用XCode 4.5和ARC创建一个UITableViewController类,我想用NSDictionary初始化它。在它的初始化器中,创建的[resourcesAsDictionary count]返回一些适当的值,但后来当我按下我的主视图中的一个按钮,该表是根据NSDictionary的条目数量构建的我初始化类的NSDictionary总是空的和[resourcesAsDictionary count]返回0.
我认为这与ARC有关?如果我把它关闭,我可以保留那个变量?但是必须有一种方法可以得到这个WITH ARC?)
相关代码:



编辑:我已经根据我收到的帮助更改了代码。
edit2:因为我能够缩小问题,这是一个有点混乱,很多阅读,我创建了一个新主题: ViewController类在创建视图时创建新实例,但它应该使用现有的一个
edit 3:已经链接的线程中解决的问题,这是一个。



ViewController.h:

  #import< UIKit / UIKit.h> 
#import< Foundation / NSJSONSerialization.h>
#import< Foundation / NSXMLParser.h>
#importResourcesTableViewController.h

@interface ViewController:UIViewController< UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource> {
//注意:此< UITableViewDelegate,UITableViewDataSource>与TableViewController无关。我的ViewController有另一个TableView。
NSDictionary * parsedResponseAsDictionary;
ResourcesTableViewController * resourceTableViewController;
...
}
...

ViewController.m:

  #importViewController.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];
... //将找到的键作为数组中的条目放置foundResources
if([foundResources count]> 0){
resourceTableViewController = [[ResourcesTableViewController alloc] initWithStyle:UITableViewStylePlain];
[resourceTableViewController setResourcesAsDictionary:parsedResponseAsDictionary];
NSLog(@Delivered%i entries。,[[resourceTableViewController resourcesAsDictionary] count]);
//可以构建TableView:启用显示资源按钮
[_showResourcesButton setAlpha:1];
[_showResourcesButton setEnabled:YES];
}
}
...
//输出:
// REST分析器[1259:c07]发送8个条目。
// REST分析器[1259:c07] viewWillAppear:(null)
// REST分析器[1259:c07]现在:0个条目。

ResourcesTableViewController.h:

  #import< UIKit / UIKit.h> 

@interface ResourcesTableViewController:UITableViewController {
}

@property(nonatomic,strong)NSDictionary * resourcesAsDictionary;

@end

ResourcesTableViewController.m:

  #importResourcesTableViewController.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;
//}

- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
return self;
}

- (void)viewDidLoad {
[super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
NSLog(@viewWillAppear:%@,self.resourcesAsDictionary);
//(null)返回这里。
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@Now:%i entries。 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 = @说明;

return cell;
}


解决方案

几种方法...



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

  @property(nonatomic,strong)NSDictionary * resourcesAsDictionary; 

然后我通过删除你的init方法改变初始化, >

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



而不是initWithDictionary have ...

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

然后设置属性...

  tvc.resourcesAsDictionary = mySourceDictionary; 

然后按TVC ...

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

...或者您正将此推送到屏幕。



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

  self.resourcesAsDictionary count]; 

这将是我的方法,这意味着你不必重写UITableViewController类的init 。



通过拥有强大的属性,你可以确保它会在所有对象的生命周围停留。通过不覆盖init,确保你不会错过任何在initWithStyle中调用的代码...



如果这不工作,我可以



在 - (void)viewWillAppear ...函数告诉我,输出...

  NSLog(@%@,self.resourcesAsDictionary); 


I now I already asked this question in my first post here but I couldn't get this solved. And I DO feel a bit inept to ask this once again again but I'm writing on my bachelor's thesis at the moment (and I'm new to XCode and Objective-C) and I really need to get this done. Pleased help me and if there is some information missing, please call for it, I'm happy to communicate with you. :-/

I'm using XCode 4.5 with ARC to create a UITableViewController class and I want to initialize it with a NSDictionary. In its initializer the created [resourcesAsDictionary count] is returning some proper value but later on when I'm pressing a button in my main view and the table is built according to the number of entries of the NSDictionary I initialized the class with, the NSDictionary is always empty and [resourcesAsDictionary count] returns 0. I assume this has to do with ARC? If I would turn that off, I could retain that variable? But there has to be a way do get this WITH ARC?) The relevant code:

edit: I already changed the code according to the help I received. edit2: Since I was able to narrow the problem down and this was a bit confusing and far to much to read in I created a new topic: ViewController class creates new instance when creating view, but it should use an existing one edit 3: Problem solved in the already linked thread, so is this one.

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;
...
}
...

Somewhere in 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;
// }

- (id)initWithStyle:(UITableViewStyle)style {
    self = [super initWithStyle:style];
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
}

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (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;
}

解决方案

I would change this in a couple of ways...

Remove the iVar for resourcesAsDictionary and set it as a property instead.

@property (nonatomic, strong) NSDictionary *resourcesAsDictionary;

Then I'd change the initialisation by removing your init method and using this property instead.

In the viewController that pushes on to this controller (i.e. where you call the initWithDictionary)...

Instead of initWithDictionary have...

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

Then set the property...

tvc.resourcesAsDictionary = mySourceDictionary;

Then push the TVC...

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

...or however you are pushing this to the screen.

Finally you'll need to change your numberOfRows... code to...

return [self.resourcesAsDictionary count];

The would be my approach and it means you don't have to override the init of the UITableViewController class.

By having the strong property you are ensuring it will stay around for the life of the owning object. And by not overriding the init you ensure that you're not missing out on any code that gets called in initWithStyle...

If this doesn't work then I can only think that there is something not right with the way you are creating the dictionary in the first place.

In the - (void)viewWillAppear... function tell me the output of...

NSLog(@"%@", self.resourcesAsDictionary);

这篇关于(solve)当调用numberOfRowsInSection时,TableView初始化程序中的变量集被忘记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆