从iOS中的另一个类重新加载表数据

从我的问题可以看出,我是iOS开发的初学者。 我看了几个教程和几个问题,但似乎没有涵盖我的情况(我可能错过了一些东西)。 我只是试图从一个类添加元素到数组,然后调用从另一个类重新加载表数据的方法。 但是,当我尝试从另一个类调用相关的方法后重新加载数据,该表无法加载(似乎没有新的数据添加)。 事实上,即使表中数组的前一个值似乎也没有了。

A类:


MyClassA.h

@interface MyClassA : UIViewController <UITableViewDelegate, UITableViewDataSource> { UITableView *tableView; NSMutableArray *Elements; } @property UITableView *tableView; @property NSMutableArray *Elements; -(void) addElement: (NSString *) ElementName; @end 

MyClassA.m

 @implementation MyClassA { NSString *ElementName[10]; } - (void) viewWillAppear:(BOOL)animated { NSLog(@"MyClassA: viewWillAppear"); ElementName[0] = @" 1 "; ElementName[1] = @" 2 "; ElementName[2] = @" 3 "; Elements = [[NSMutableArray alloc]initWithObjects:ElementName[0], ElementName[1], ElementName[2],nil]; self.tableView.dataSource = self; // The table successfully loads with the data element } -(void) addElement: (NSString *) ElementName { NSLog(@"Entered addElement"); // This method is successfully accessed Elements = [[NSMutableArray alloc]initWithObjects:ElementName[0], ElementName[1], ElementName[2],nil]; // The problem is here, printing data in this array shows they have no value [self.tableView reloadData]; // The problem is here. This does not load the data } 

B类:


MyClassB.h

 @class MyClassA @interface MyClassB : UIViewController @property (nonatomic, strong) MyClassA *MyClassACall -(IBAction) MyButtonClicked: (id) sender; @end 

MyClassB.m

 @implementation MyClassB @synthesize MyClassACall; -(id) init { self = [super init] if (self) { NSLog(@"MyClassB init"); MyClassACall = [[MyClassA alloc] init]; } return self; } -(IBAction)MyButtonClicked:(id)sender { NSLog("My button is clicked"); [self.MyClassAcall addElement:@"NewElement"]; } 

我成功地获取了所有的NSlogs,并且使用提供的数据正确加载了表格。 但是,当尝试通过从另一个类中加载方法来添加数据时,表数据保持不变,并且不会重新加载。 我在这里错过了什么?

我没有加载整个代码来保持这个简单。 我希望这是有道理的,请让我知道,如果我能澄清。 如果存在类似的问题,请将其指向我,并感谢您的帮助。

我在这里为你做了一个迷你教程。

好吧,让我们说我们有这样的情况:

有两个视图控制器 – ViewControllerAViewControllerB

ViewControllerA将负责添加项目。

ViewControllerB将负责显示这些项目。

所以ViewControllerA将如下所示:

屏幕截图1

和ViewControllerB将如下所示:

截图2

ViewControllerA.h

 #import <UIKit/UIKit.h> @interface ViewControllerA : UIViewController @property (nonatomic, strong) NSMutableArray *arrItems; @end 

在这里,我们将名为arrItems的数据源存储为一个NSMutableArray 。 稍后我们将把这个数组传递给ViewControllerB。

ViewControllerA.m

 #import "ViewControllerA.h" #import "ViewControllerB.h" - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self initViews]; } -(void)initViews { self.view.backgroundColor = [UIColor whiteColor]; self.navigationItem.title = @"View Controller A"; UIButton *btnAddItem = [[UIButton alloc] initWithFrame:CGRectMake(60, 200, 200, 50)]; [btnAddItem setTitle:@"Add Item" forState:UIControlStateNormal]; btnAddItem.backgroundColor = [UIColor greenColor]; btnAddItem.layer.cornerRadius = 5.0; [btnAddItem addTarget:self action:@selector(addItem) forControlEvents:UIControlEventTouchUpInside]; UIButton *btnViewData = [[UIButton alloc] initWithFrame:CGRectMake(60, 300, 200, 50)]; [btnViewData setTitle:@"View Data" forState:UIControlStateNormal]; btnViewData.backgroundColor = [UIColor blueColor]; btnViewData.layer.cornerRadius = 5.0; [btnViewData addTarget:self action:@selector(viewData) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btnAddItem]; [self.view addSubview:btnViewData]; // init empty array to hold data source items self.arrItems = [[NSMutableArray alloc] init]; } -(void)addItem { [self.arrItems addObject:@"New Element"]; NSLog(@"added a new element to arrItems, arrItems now has %u items", self.arrItems.count); } -(void)viewData { ViewControllerB *vcB = [[ViewControllerB alloc] initWithItems:self.arrItems]; [self.navigationController pushViewController:vcB animated:YES]; } 

对于绿色的“添加项目”button,我们使用这样的方法将项目添加到我们的数据源:

 -(void)addItem { [self.arrItems addObject:@"New Element"]; NSLog(@"added a new element to arrItems, arrItems now has %u items", self.arrItems.count); } 

你会注意到当你点击绿色button,你会得到一个控制台日志,告诉你有多less项目是在你的数组。

现在当我们完成添加项目时,我们有蓝色的“View Data”button,它将ViewControllerB推到导航堆栈上:

 -(void)viewData { ViewControllerB *vcB = [[ViewControllerB alloc] initWithItems:self.arrItems]; [self.navigationController pushViewController:vcB animated:YES]; } 

ViewControllerB.h

 #import <UIKit/UIKit.h> @interface ViewControllerB : UIViewController <UITableViewDataSource, UITableViewDelegate> -(id)initWithItems:(NSArray *)arrItems; // ---------------------------------------------------------------- // view controller B data source is set from // view controller A using init method shown above // ---------------------------------------------------------------- @property (nonatomic, copy) NSArray *arrItems; @property (nonatomic, strong) UITableView *tableView; @end 

在这里,我们已经声明了一个带有NSArray参数的init方法。 这个方法将允许我们将ViewControllerA的数据源数组注入到ViewControllerB中。

按照惯例,我们也有ViewControllerB中的tableView。

ViewControllerB.m

 -(id)initWithItems:(NSArray *)arrItems { self = [super init]; if(self) { self.arrItems = arrItems; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self initViews]; } -(void)initViews { self.navigationItem.title = @"View Controller B"; self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)]; self.tableView.dataSource = self; self.tableView.delegate = self; [self.view addSubview:self.tableView]; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.arrItems.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"cellID"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if(cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } cell.textLabel.text = self.arrItems[indexPath.row]; return cell; } 

请注意,在initWithItems:方法中,我们将传入的参数arrItems的数据源存储到ViewControllerB的self.arrItems

 -(id)initWithItems:(NSArray *)arrItems { self = [super init]; if(self) { self.arrItems = arrItems; } return self; } 

然后,ViewControllerB可以使用这些数据并将其显示在tableView数据源方法中。

所以如果你单击添加项目五次,你最终会得到这样的结果:

屏幕截图3

Xcode的控制台还logging添加5个项目:

 2014-12-08 10:33:39.195 DataPassingDemo[1211:25705] added a new element to arrItems, arrItems now has 1 items 2014-12-08 10:33:40.099 DataPassingDemo[1211:25705] added a new element to arrItems, arrItems now has 2 items 2014-12-08 10:33:40.619 DataPassingDemo[1211:25705] added a new element to arrItems, arrItems now has 3 items 2014-12-08 10:33:41.123 DataPassingDemo[1211:25705] added a new element to arrItems, arrItems now has 4 items 2014-12-08 10:33:41.667 DataPassingDemo[1211:25705] added a new element to arrItems, arrItems now has 5 items 

这更清楚吗?

首先,我认为,以C语言编写数组的方式是elementName [10],但是这样就可以溢出,你可以简单地使用带有文本的“objective-c”风格,或者“initWithCapacity:10”。 还简化你的代码,改变它在这种方式:

 @implementation MyClassA { //NSString *ElementName[10]; // you already have NSMutableArray, why did you do this ? } - (void) viewWillAppear:(BOOL)animated { NSLog(@"MyClassA: viewWillAppear"); Elements = [@[@"1",@"2",@"3"] mutableCopy]; self.tableView.dataSource = self; } -(void) addElement: (NSString *) ElementName { NSLog(@"Entered addElement"); // This method is successfully accessed // You already have initialized array, you need simply to add new element [elements addObject: elementName]; [self.tableView reloadData]; } 

可以,然后呢。 几件事…

您定义元素数组的方式是一种老办法,您不需要声明只是属性。

MyClassACall = [[MyClassA alloc] init]; 正在创build一个MyClassA的新实例,所以你设置的任何东西都不会出现在你的视图控制器上。

如果你需要在一个视图控制器上显示一个模型,并在另一个视图控制器中更新它,我build议集中这个模型,这样两个视图控制器都可以访问/改变这个模型。 单身人士可能是最简单的方法来实现这一点。