NSMutableArray返回NULL

时间:2011-11-04 02:08:55

标签: objective-c ios uitableview delegates nsmutablearray

我尝试从另一个类(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。我甚至不确定这是否是最佳方式。任何建议将不胜感激。

5 个答案:

答案 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

在视图之间进行通信的另一种方法是将一个委托(回调)传递给另一个视图。这允许其他视图不与另一个视图耦合 - 它只知道委托的协议。

What exactly does delegate do in xcode ios project?

答案 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);
}
}