【问题标题】:iOS Reload Table Methods [closed]iOS重新加载表方法[关闭]
【发布时间】:2013-03-09 05:50:07
【问题描述】:

我有一个标签栏,第一个视图需要登录 alertview 并且工作正常。当我切换到下一个选项卡时,我有一个表格视图。

我正在使用 JSON 在我从表视图控制器中的 viewDidLoad 方法以及另一个登录过程调用的方法中从在线获取数据。我想要两个部分,每个部分中的数据取决于我从解析数据中获得的属性之一。

问题是,在解析数据时,表格视图方法已经完成,所以我得到 0 节和 0 行并且没有数据显示。 所以我的问题是,有没有办法重新加载 no of section 方法、 no of rows 方法和 cellForRowAtIndexPath 方法。如果我重新加载整个表格视图,我会收到无限的警报视图,要求登录:/

编辑:

     #import "BooksViewController.h"
     #import "Me.h"
     #import "SBJson.h"

     @interface BooksViewController ()

     @end

     @implementation BooksViewController

     @synthesize name = _name;
     @synthesize ID = _id;
     @synthesize extended = _extended;
     @synthesize returned = _returned;
     @synthesize Date = _date;

     -(void) dealloc
     {
         self.name = nil;
         self.ID = nil;
         self.extended = nil;
         self.returned = nil;
         [super dealloc];
     }

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

             BooksBorrowed = [[NSMutableArray alloc]init];
             BorrowedDates = [[NSMutableArray alloc]init];
             BorrowedIDs = [[NSMutableArray alloc]init];
             BorrowedExtensions = [[NSMutableArray alloc]init];
             BorrowedReturns = [[NSMutableArray alloc]init];

             /*message = [[UIAlertView alloc] initWithTitle:@"Please Login with your User                            ID and Password"
              message:nil
              delegate:self
              cancelButtonTitle:@"Cancel"
              otherButtonTitles:@"Continue", nil];

              [message setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];*/
             //book = [[BooksViewController alloc]init];
             me = [[Me alloc]init];
         }
         return self;
     }

     - (void)MyBooks
     {
NSString *authFormatString =
@"http://localhost:8888/Jineel_lib/bookBorrowed.php?uid=%d";

NSString *urlString = [NSString stringWithFormat:authFormatString, 1];

NSURL *url = [NSURL URLWithString:urlString];

NSString *contents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

response1 = [contents JSONValue];
if(contents)
{
    NSLog(@"contents : %@",contents);
    BookName = [[NSString alloc]init];
    DateBorrowed = [[NSString alloc]init];
    BookID = [[NSString alloc]init];
    BookExtended = [[NSString alloc]init];
    BookReturned = [[NSString alloc]init];

    BookName = [response1 valueForKey:@"BookName"];
    BookID = [response1 valueForKey:@"BookID"];
    DateBorrowed = [response1 valueForKey:@"DateBorrowed"];
    BookExtended = [response1 valueForKey:@"Extended"];
    BookReturned = [response1 valueForKey:@"Returned"];

    [BooksBorrowed addObject:BookName];
    [BorrowedDates addObject:DateBorrowed];
    [BorrowedIDs addObject:BookID];
    [BorrowedReturns addObject:BookReturned];
    [BorrowedExtensions addObject:BookExtended];

    NSLog(@"Arrays are : %@, %@, %@, %@, %@", BooksBorrowed, BorrowedDates, BorrowedIDs, BorrowedReturns, BorrowedExtensions);
         }
     }


     - (void)viewDidLoad
     {
         [super viewDidLoad];

         // Uncomment the following line to preserve selection between presentations.
         // self.clearsSelectionOnViewWillAppear = NO;

         // Uncomment the following line to display an Edit button in the navigation bar          for this view controller.
         // self.navigationItem.rightBarButtonItem = self.editButtonItem;
         [self MyBooks];
     }

     - (void)didReceiveMemoryWarning
     {
[sup         er didReceiveMemoryWarning];
         // Dispose of any resources that can be recreated.
     }

     #pragma mark - Table view data source

     - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
     {
         // Return the number of sections.
         return 1;
     }

     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(         (NSInteger)section
     {
         // Return the number of rows in the section.
         NSLog(@"rows %d", [BooksBorrowed count]);
         return [BooksBorrowed count];
     }

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
     {
         static NSString *CellIdentifier = @"Cell";
         UITableViewCell *cell = [tableView          dequeueReusableCellWithIdentifier:CellIdentifier];
         if (cell == nil) {
             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault          reuseIdentifier:CellIdentifier] autorelease];
         }

                  bookName = BooksBorrowed[0];

                  cell.textLabel.text = bookName;
                  return cell;
     }

     @end

【问题讨论】:

  • 这与 Xcode完全无关
  • 等到所有数据都解析完再重新加载怎么样?
  • 真诚地我不明白你的问题是什么。如果您调用 UITableView 的 reloadData 方法,您将获得所有调用的委托方法(n. of section,n. of rows for section 和 cellForRowAtIndexPath)。并且不会调用拥有表视图的视图/视图控制器的任何方法(您不直接从这些方法内部调用)
  • @AntonioE。这就是问题:/,我正在解析一些东西,根据我解析的数据,我想设置我的表格视图,但我的表格视图在解析之前加载
  • 你为什么要告诉运行循环运行?您真的应该阅读一些基本的 iOS 网络教程并尝试遵循这些教程 - WWDC 视频和示例代码可能是开始的好地方。也不要用大写字母命名所有内容,这会使阅读变得更加困难。如果您采用您正在开发的平台的约定,您会发现其他人会更好地理解您的代码并为您提供更多帮助。

标签: objective-c xcode cocoa-touch uitableview


【解决方案1】:

应在后台线程上获取数据,以免 UI 被阻塞。获取数据后,更新表视图数据源并重新加载表视图。这必须在主线程上完成。

下面的代码应该展示了这个想法:

- (void)updateMyBooks
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // Fetch data on a background thread:
        NSURL *url = ...;
        NSString *contents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
        if (contents) {
            NSMutableArray *newBooksBorrowed = [NSMutableArray array];

            // ... Parse JSON response and add objects to newBooksBorrowed ...

            dispatch_sync(dispatch_get_main_queue(), ^{
                // Update data source array and reload table view.
                BooksBorrowed = newBooksBorrowed;
                [self.tableView reloadData];
            });
        }
    });
}

【讨论】:

  • 这是有道理的。非常感谢...我在哪里调用这个方法? ViewDidLoad 还是?
  • 嘿,当我把它用来设置我的桌子时,它崩溃了,你能告诉我哪里出错了吗? cell.textLabel.text = [BooksBorrowed objectAtIndex:0];
  • @user2176687:您可以在 viewDidLoad 中调用它。您有任何有关崩溃的错误消息吗?
  • 不,它只是崩溃,日志中没有任何内容
  • @user2176687:那就很难帮忙了。您应该在调试器中检查BooksBorrowed[BooksBorrowed objectAtIndex:0] 的值和类。
【解决方案2】:

你有两种方法可以使用。

在当前线程中等待解析结束。

-(void)aFunc {
    //your job A
    while (A is not finished) {
        // If A job is finished, a flag should be set. and the flag can be a exit condition of this while loop
        // This executes another run loop.
       [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

[yourTable reloadData];
}

或仅加载特定部分。

– reloadRowsAtIndexPaths:withRowAnimation:
– reloadSections:withRowAnimation:
– reloadSectionIndexTitles

编辑:

另一种方法是GCD,使用串行队列。 dispatch_sync(),block 已入队,直到 block 执行完毕,函数才会返回。

【讨论】:

  • 我想等到所有数据都被解析完然后重新加载。这就是我的想法。如何调用tableview委托的具体方法?[self reloadRowsAtIndexPaths:withRowAnimation:YES]?
  • 检查编辑后的答案
  • 我已经尝试过 [self.tableview reloaddata] 但是当我这样做时,它也会调用 view did load 方法,然后我会得到登录 alertview 的无限循环:/
  • 我猜你在代理内部解析,把它移出。
  • 我在这段代码中遇到错误:cell.textLabel.text = bookName;
猜你喜欢
  • 2014-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-31
  • 2015-08-22
  • 2010-10-14
  • 2011-02-07
  • 1970-01-01
相关资源
最近更新 更多