我尝试从另一个类(secondViewController)向NSMutableArray添加对象,然后将它添加到我的FirstViewController中的UITableView,但是当我使用NSLog打印它时它返回null。这是我的设置。
FirstViewController.h:
@interface FirstViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>{
IBOutlet UITableView *mytableview;
NSMutableArray *mytableinfo;
}
@property (nonatomic,retain) IBOutlet UITableView *mytableview;
@property (retain) IBOutlet NSMutableArray *mytableinfo;
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
@synthesize mytableinfo,mytableview;
-(IBAction)addShift:(id)sender{
SecondViewController *secondViewController = [[SecondViewController alloc]init];
[self presentModalViewController:secondViewController animated:YES];
}
- (void)viewDidLoad
{
mytableinfo = [[NSMutableArray alloc]init];
[super viewDidLoad];
}
SecondViewController.m
#import "SecondViewController.h"
#import "FirstViewController.h"
@implementation SecondViewController
@synthesize dateformatter,mydatepicker,startingTime;
-(IBAction)saveShift:(id)sender{
FirstViewController *firstViewController = [[FirstViewController alloc]init];
[firstViewController.mytableinfo addObject:@"Hello world"];
NSLog(@"%@",firstViewController.mytableinfo);
[self dismissModalViewControllerAnimated:YES];
}
我的目标是最终从mytableview
提供mytableinfo
。我甚至不确定这是否是最佳方式。任何建议将不胜感激。
答案 0 :(得分:4)
在SecondViewController中,您正在使用alloc init创建FirstViewController。此时,FirstViewController上的mytableinfo为nil,因为直到viewDidLoad才分配。
什么加载SecondViewController?因为你是模态地解雇它。如果它是FirstViewController,那么当你分配init第一个视图控制器时,你不会调用以模态方式呈现它的实例。
将一个视图捅到另一个视图上也不是非常MVC。它创建了在视图层耦合并在视图层修改数据的代码。最好创建一个模型,并让两个视图都修改该模型。
How to create a NSMutable Array which can access from different view controllers
在视图之间进行通信的另一种方法是将一个委托(回调)传递给另一个视图。这允许其他视图不与另一个视图耦合 - 它只知道委托的协议。
答案 1 :(得分:2)
有一点在我的“SecondViewController”中看起来很奇怪,你把它当作一个模态来消除它。
我的问题是......谁开始了模态演示?
一个“FirstViewController”?如果是这样的话,为什么要创建一个新的,在解除第二个时,启动它的第一个将恢复它的活动。
另一件我不明白的事情是UIViewController的指定初始化程序是
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
如果不需要与nib相关联,则可以将nil传递给两个参数。
最后,如果你需要从第一个模拟呈现的第二个VC返回一个NSMutableArray到第一个ViewController(VC),你可以在第二个VC中执行此操作:
- (id)initWithMutableArray:(NSMutableArray *)theArray {
//... put standard init code here }
并将其作为第二个VC的默认初始化程序。但只有当第二个VC绝对需要一个可变数组时才有意义。
现在我好奇,因为我不理解这一行
@property (retain) IBOutlet NSMutableArray *mytableinfo;
为什么这是IBOutlet?这看起来像是一个潜在的问题来源。 IBOutlet通常是指向xib文件中UI元素的指针。
答案 2 :(得分:1)
当在应用程序的过程中使用可以由多个模态视图修改的数组填充UITableView时,我发现使用NSUserDefaults的最佳方法之一。您可以创建一个NSUserDefaults对象以供参考,如下所示:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
然后你可以在默认情况下为每个键分配对象,这实际上只是一个plist(它只是一个包含与之关联的对象的键列表。
那么,当您想要将数组存储在默认值中时,您可以说:
[defaults setObject:mytableinfo forKey:@"tableInformationKey"];
然后,只要您想访问该数据,就可以说:
NSMutableArray* tableInfoCopy = [defaults mutableArrayValueForKey:@"tableInformationKey"];
这将使您获得存储在NSUserDefaults中的数组的副本(可以从应用程序的任何位置访问NSUserDefaults),这样您就可以对刚刚创建的可变数组进行更改。完成更改后,您可以将其重新分配给NSUserDefaults,如下所示:
[defaults setObject:tableInfoCopy forKey@"tableInformationKey"];
所以当你在
中填充你的UITableView时- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Foobar"];
if (cell == nil) {
// No cell to reuse => create a new one
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Foobar"] autorelease];
// Initialize cell with some customization
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.textLabel.textColor = [UIColor blackColor];
}
NSArray* arrayOne = [defaults objectForKey:@"tableInformationKey"];
NSString* title = [arrayTwo objectAtIndex:indexPath.row];
//this goes to the index in the array of whatever cell you are
// at, which will populate your table view with the contents of this array (assuming the array contains strings)
// Customize cell
cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:25];
return cell;
}
答案 3 :(得分:0)
使用它们最简单的方法是将数组放入AppDelegate
// populate appDelegate's array
AppDelegate *appDelegate = (myAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.arrayMyTableInfo addObject:@"HelloWorld"];
答案 4 :(得分:0)
以下是您如何做我的建议:
(这是您的代码更新的一部分)
这是在你的第二个视图中,这是将数组传递到第二个视图的众多方法之一。
@synthesize array4Test;
- (id)initWithMutableArray:aMutableArray
{
self = [self initWithNibName:nil bundle:nil];
if (self)
{
self.array4Test = aMutableArray;
}
return self;
}
- (void)dealloc
{
// HERE clean up the property is set to retain.
self.array4Test = nil;
[super dealloc];
}
以下是firstView的代码
-(IBAction)addShift:(id)sender{
SecondViewController *secondViewController = [[SecondViewController alloc] initWithMutableArray:self.mytableinfo];
[self presentModalViewController:secondViewController animated:YES];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.mytableview reloadData];
NSString *aString = [mytableinfo lastObject];
if (aString)
{
NSLog(@"This just came back from the second View\n%@", aString);
}
}