从 appdelegate 调用 UITableView 的 reloadData 方法

Posted

技术标签:

【中文标题】从 appdelegate 调用 UITableView 的 reloadData 方法【英文标题】:Calling UITableView's reloadData method from appdelegate 【发布时间】:2011-03-17 20:00:16 【问题描述】:

我遇到了 UITableView reloadData 方法的严重问题。我有一个 UIViewController 类,WiGiMainViewController 里面有一个 UITableView 和 NSMuttableArray。我目前正在 AppDelegate 中发出网络调用,并在下载数据后向 WiGiMainViewController 发布通知。在我的通知选择器方法 reloadWigiList 中,我传递了一个包含最近下载的项目的 NSArray。然后我用传入的数组初始化 WiGiMainViewController 的 NSMuttableArray 并继续在我的 UITableView 对象上调用 reloadData()。我可以从 nslog 语句中看到 numberOfRowsInSection 在重新加载时触发,而不是 cellForRowAtIndexPath,因此导致 UI 不会使用新下载的项目重新加载 UITableView。我已经验证了在主线程上调用了 reloadData 方法,并且数据源委托在 IB 中设置,并以编程方式在 WiGiMainViewController 的 viewDidLoad 方法中设置。任何想法为什么我的 UITableView,wigiLists 没有重新加载数据,特别是没有调用 cellForRowAtIndexPath 方法?

@interface WiGiMainViewController : UIViewController<FBRequestDelegate,UITableViewDelegate, UITableViewDataSource> 

//setup UI
UITableView *wigiLists;

WiGiAppDelegate *myAppDelegate;
NSMutableArray *itemsList;


 @property (nonatomic, retain) WiGiAppDelegate *myAppDelegate;
 @property (nonatomic, retain) IBOutlet UITableView *wigiLists;
 @property (nonatomic, retain) NSMutableArray *itemsList;

-(void) reloadWigiList: (NSNotification*) notification;
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView;
-(NSInteger) tableView: (UITableView*) tableView numberOfRowsInSection:(NSInteger) section;
-(UITableViewCell *) tableView: (UITableView*)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath;

@end


@implementation WiGiMainViewController

@synthesize headerLabel = _headerLabel, userNameLabel = _userNameLabel, facebookPicture = _facebookPicture,
myAppDelegate, wigiLists, itemsList;

- (void)viewDidLoad 
NSLog(@"In viewDidLoad");
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadWigiList:) name:@"wigiItemUpdate" object:nil];


// get appdelicate
self.myAppDelegate = (WiGiAppDelegate*) [[UIApplication sharedApplication] delegate];   
self.itemsList = [[NSMutableArray alloc] init];
//setup tableview
 self.wigiLists = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
    self.wigiLists.delegate = self;
self.wigiLists.dataSource = self;
//set up view
[self.headerLabel setText:self.myAppDelegate.HEADER_TEXT];
//check if user is logged in
if (self.myAppDelegate.isLoggedIn) 
    //user is logged in
    NSLog(@"HERE");
    //get facebook information to populate view
    [self retrieveFacebookInfoForUser];
    //[self.myAppDelegate retrieveWigiItems];
else 
    //user is not logged in
    NSLog(@"user not logged in");
    //show login modal

//[self.wigiLists reloadData];
[super viewDidLoad];


-(void) reloadWigiList: (NSNotification *) notification 
if ([NSThread isMainThread]) 
    NSLog(@"main thread");
else
    NSLog(@"METHOD NOT CALLED ON MAIN THREAD!");

NSLog(@"notification recieved:%@", notification.userInfo);

NSLog(@"in reloadwigilists:%@", wigiLists );
NSLog(@"list size:%@", self.itemsList);
NSLog(@"delegate:%@",self.wigiLists.delegate);
NSLog(@"datasource:%@",self.wigiLists.dataSource);
//populate previously empty itemsList
[self.itemsList setArray:notification.userInfo];
NSLog(@"list size:%@", self.itemsList);
[self.wigiLists reloadData];



/////////////////////////////////////
// UITableViewDelegate protocols
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView 
//NSLog(@"numberofsections: %@", [self.itemsList count]);
return 1;
   

-(NSInteger) tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger) section 
NSLog(@"7t87giuiu%@",self.itemsList);
NSLog(@"numberofrows: %i", [self.itemsList count]);


    return [self.itemsList count];

//return 6;


【问题讨论】:

你能把调用reloadData的代码贴在tableView上吗?另外,您如何检查是否正在调用 cellForRowAtIndexPath:? 已发布代码...我将日志语句放在 cellForRowAtIndexPath 中,让我知道它是否以及何时被调用。我可以从日志语句中看到 numberOfRowsInSection 被调用并更新了 itemsList 计数。 我更新了代码,现在使用通知让 UIViewController 知道何时重新加载数据,但仍然是同样的问题 【参考方案1】:

我要做的第一件事是在 [self.wigiMainViewController.wigiLists reloadData] 上设置一个断点

如果 wigiLists tableView 在调试器中显示为空,那么它可能是尚未设置的插座。另外,请确保已设置委托和数据源。

【讨论】:

我知道委托和数据源不为空,因为我在尝试重新加载数据之前将它们打印在日志中。我将放置断点并尝试解决这个问题。谢谢 我已经验证了 tableview,在我的例子中 wigiItems 在调用 reloadData 时不为空。 如果我将 numberOfRowsInSection 更改为在 itemsList 计数为 0 时返回 1,那么当我滚动时我可以在 tableview 中看到第一个 Item。不过不确定这是否相关。【参考方案2】:

哇!经过 3 天的努力解决这个问题,这是一件非常简单的事情。在 WiGiMainViewController 的 ViewDidLoad 方法中,我正在初始化我的 tableview:

self.wigiLists = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];

因为我已将我在 IB 中创建的 tableView 链接到我的实例 wigiLists,在 ViewDidLoad 中分配和初始化覆盖了我在 IB 中创建并当前正在显示的 tableView 的链接。摆脱这条线可以解决所有问题。

【讨论】:

以上是关于从 appdelegate 调用 UITableView 的 reloadData 方法的主要内容,如果未能解决你的问题,请参考以下文章

从 AppDelegate 调用 navigationController

从 AppDelegate 调用委托函数不起作用

如何从appdelegate调用方法[重复]

如何从 AppDelegate 调用在 ViewController 中声明的方法

无法从 AppDelegate 调用 ViewController 方法

AppDelegate 从 m File + presentViewController 调用函数