Objective c NSMutableArray在调用modalViewController后重置
由@T-X解决。我在代码中用“//SOLUTION”标记了更改强> 我有以下问题,如果我显示ModalViewController,NSMutableArray“projectsArray”将重置 这是我的密码: 这里是.h文件:Objective c NSMutableArray在调用modalViewController后重置,objective-c,ipad,methods,nsmutablearray,modalviewcontroller,Objective C,Ipad,Methods,Nsmutablearray,Modalviewcontroller,由@T-X解决。我在代码中用“//SOLUTION”标记了更改 我有以下问题,如果我显示ModalViewController,NSMutableArray“projectsArray”将重置 这是我的密码: 这里是.h文件: // ViewController.h #import <UIKit/UIKit.h> @class AddProject; @interface ViewController : UIViewController <UITableViewD
// ViewController.h
#import <UIKit/UIKit.h>
@class AddProject;
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *projectsTableView;
UIAlertView *reallyDelete;
BOOL candelButtonClicked;
NSIndexPath *actualIndexPath;
NSMutableArray *projectsArray;
NSInteger ID;
NSString *NAME;
AddProject *addProject;
**ViewController *viewContr; // SOLUTION**
}
- (IBAction)addNewProject:(id)sender;
- (void)addToTableView:(NSString *)projectName;
@property (nonatomic, retain) UIAlertView *reallyDelete;
@property (nonatomic) NSInteger cancelButtonIndex;
@property IBOutlet UITableView *projectsTableView;
@property (nonatomic, retain) AddProject *addProject;
**@property (nonatomic, retain) ViewController *viewContr; // SOLUTION**
@end
我已经使用断点测试了代码,可以在AddProject类“viewDidLoad”开始加载时找到问题所在。但是我不知道为什么它会重置数组。您应该在视图控制器的init方法中分配projectsArray,而不是在viewDidLoad中<代码>项目数组=[[NSMutableArray alloc]init]代码>加载视图时分配了一个新的空数组转速表。好的,通过stackoverflow聊天解决了我的问题。最终解决方案的提示来自user@T-X。我在问题的代码中添加了这些提示。它们标有“//解决方案” 在添加项目视图控制器的viewDidLoad方法中,删除该行
viewContr=[[ViewController alloc]init]代码>。现在创建变量
ViewController
a类属性中的viewContr
。还合成
信息技术最后在-(iAction)addNewProject:(id)sender
方法中,
在显示控制器之前,请执行以下操作:添加ProjectView.viewContr=self代码>。它会解决你的问题
(引用自|)您可以从ViewController
屏幕导航到addproject
屏幕。在addproject
屏幕中,您添加了一个新项目,并希望将此信息委托回您所在的ViewController
屏幕
现在,您正试图在您的AddProject
中有一个ViewController
的实例,您在viewDidLoad
方法中新实例化了该实例,当添加项目时,您可以通过在其上调用-(void)addToTableView:(NSString*)projectName
向其提供信息。
这不起作用,因为-您分配的ViewController
的实例是一个新实例,而不是您从中导航的实例。当您执行alloc+init
时,您将获得一个新对象。因此,尽管在ViewController
上调用了addToTableView:
,但它不起作用,因为接收此消息的ViewController
实例是一个新实例,而不是您导航的实例
因此,您只需在Add项目
中设置一个ViewController
属性,您可以在导航之前设置该属性。然后你们可以向这个属性发送消息——正如在文本中所解释的
我想说的是,不管这个东西如何工作,它在两个控制器之间提供了紧密耦合
理想情况下,这可以通过将ViewController
(导航位置)作为addproject
(导航位置)的代表来完成。然后,addproject
可以通过类似于-(void)addProjectController:(AddProjectViewController*)controller diddproject:(NSString*)projectName的方式将添加的项目委托给它的委托。这将使两个视图控制器之间失去耦合。要了解委派概念,请参阅。或者,搜索其他堆栈溢出帖子。在viewDidLoad
方法中实例化也不错。视图仅加载一次(当请求视图控制器的视图时),并且仅当它们由于内存不足而卸载时才会再次加载。在这种情况下,程序员有责任在viewDidUnload
方法或direceivememorywarning
方法中释放它们,这取决于是否可以轻松地重新创建或其他原因viewDidLoad
和viewDidUnload
是视图生命周期方法的一部分。因此,viewDidLoad
中的分配也让您有机会在viewDidUnload
方法中释放其中的分配,这是一种很好的做法,就像内存不足时一样,应释放不需要的分配以释放内存。如果您在init
方法中进行分配,问题是您将在内存不足的情况下在哪里释放它们并重新创建它们?您是对的,但从这个问题中我得到的印象是,projectArray应该在视图控制器的整个生命周期内保持不变。是的,它应该持续存在,因为如果被释放,用户将丢失所有添加的项目。他可以在viewDidLoad
方法中执行if(!projectsArray){//allocate projectsArray…}
以防止每次加载视图时分配它(从而丢失以前添加的对象),或者按照您的建议将其移动到init
方法中。
// ViewController.m
#import "ViewController.h"
#import "CustomTableCell.h"
#import "AddProject.h"
@interface ViewController ()
@end
@implementation ViewController
**@synthesize viewContr; // SOLUTION**
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
projectsArray = [[NSMutableArray alloc] init];
ViewController *element = [[ViewController alloc] init];
element->ID = 1;
element->NAME = @"Demo project";
NSLog(@"viewdidload");
[projectsArray addObject:element];
NSLog(@"1. Array length: %d", [projectsArray count]);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([projectsArray count] < 1) {
NSLog(@"2. Array length: 0");
return 0;
} else {
NSLog(@"2. Array length: %d", [projectsArray count]);
return [projectsArray count];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customTableCellIdentifier = @"CustomTableCell";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:customTableCellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
ViewController *element = [[ViewController alloc] init];
element = [projectsArray objectAtIndex:indexPath.row];
cell.nameLabel.text = element->NAME;
cell.prepTimeLabel.text = [NSString stringWithFormat:@"%i", element->ID];
NSLog(@"3. Array length: %d", [projectsArray count]);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
reallyDelete = [[UIAlertView alloc] initWithTitle:@"Deleting" message:@"Do your really want to delete that row?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil];
[reallyDelete show];
actualIndexPath = indexPath;
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != [reallyDelete cancelButtonIndex])
{
//If "Yes" clicked delete
[projectsArray removeObjectAtIndex:actualIndexPath.row];
NSLog(@"delete row");
[self.projectsTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:actualIndexPath, nil] withRowAnimation:YES];
[self.projectsTableView reloadData];
}
}
#pragma mark Edit
- (IBAction)addNewProject:(id)sender {
NSLog(@"4. Array length: %d", [projectsArray count]);
AddProject *addProjectView = [[AddProject alloc] initWithNibName:@"AddProject" bundle:nil];
NSLog(@"4.1 Array length: %d", [projectsArray count]);
addProjectView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
NSLog(@"4.2 Array length: %d", [projectsArray count]);
addProjectView.modalPresentationStyle = UIModalPresentationFormSheet;
NSLog(@"4.3 Array length: %d", [projectsArray count]);
**addProjectView.viewContr = self; // SOLUTION**
[self presentModalViewController:addProjectView animated:YES];
NSLog(@"4.4 Array length: %d", [projectsArray count]);
addProjectView.view.superview.frame = CGRectMake(addProjectView.view.center.x/2.5, addProjectView.view.center.y/3, 800, 600);
NSLog(@"4.5 Array length: %d", [projectsArray count]);
}
- (void)addToTableView:(NSString *)projectName
{
NSLog(@"Project Array: %@", projectsArray);
NSLog(@"addToTableView: %@", projectName);
NSLog(@"5. Array length: %d", [projectsArray count]);
ViewController *element = [[ViewController alloc] init];
element->ID = 2;
element->NAME = projectName;
[projectsArray addObject:element];
NSLog(@"6. Array length: %d", [projectsArray count]);
[self.projectsTableView reloadData];
[self.projectsTableView setNeedsDisplay];
}
- (void)viewDidUnload
{
[self setProjectsTableView:nil];
self.projectsTableView = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
@end
// AddProject.h
#import <UIKit/UIKit.h>
@class ViewController;
@interface AddProject : UIViewController
{
IBOutlet UITextField *projectName;
ViewController *viewContr;
}
- (IBAction)back:(id)sender;
- (IBAction)next:(id)sender;
@property (nonatomic, retain) ViewController *viewContr;
@end
// AddProject.m
#import "AddProject.h"
#import "ViewController.h"
@interface AddProject ()
@end
@implementation AddProject
**@synthesize viewContr; // SOLUTION I've mist to synthesize it**
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
**// SOLUTION no new allocation/init of ViewController**
}
- (IBAction)back:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)next:(id)sender
{
[viewContr addToTableView:projectName.text];
[viewContr.projectsTableView reloadData];
[viewContr.projectsTableView setNeedsDisplay];
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidUnload
{
projectName = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
@end