I've been trying to add a simple bookmarks facility to my app for my dissertation at uni. Im new to iPhone development so really I don't understand whats happening.
What im trying to do is add an object (string) to the array but what I've done doesnt work at all.
I got my array set up in my AppDelegate and it populates a table view in the BookmarksViewController.m file.
My application consists of a tab bar and navigation bar but I've chopped all that out here to make it easier to read.
Here is the code:
SETTING UP THE ARRAY
DissertationAppDelegate.h
#import <UIKit/UIKit.h>
@class DissertationViewController;
@interface DissertationAppDelegate : NSObject <UIApplicationDelegate> {
NSMutableArray *array;
UIWindow *window;
DissertationViewController *viewController;
}
@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) NSMutableArray *array;
@end
DissertationAppDelegate.m
#import "DissertationAppDelegate.h"
@implementation DissertationAppDelegate
@synthesize window;
@synthesize array;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions {
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:@"%@/arraySaveFile", documentsDirectory];
array = [[NSMutableArray alloc] init];
[array addObject:@"One"];
[array addObject:@"Two"];
[array addObject:@"Three"];
[array writeToFile:fullFileName atomically:NO];
[self.window makeKeyAndVisible];
}
POPULATING THE TABLE VIEW WITH THE ARRAY
BookmarksViewController.h
@interface BookmarksViewController : UITableViewController {
NSMutableArray *bookmarksArray;
}
@property (nonatomic, retain) NSMutableArray *bookmarksArray;
BookmarksViewController.m
#import "BookmarksViewController.h"
@synthesize bookmarksArray;
- (void)viewDidLoad {
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMa开发者_StackOverflow中文版sk, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:@"%@/arraySaveFile", documentsDirectory];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:fullFileName];
bookmarksArray = array;
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [bookmarksArray 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];
}
// Configure the cell...
cell.textLabel.text = [bookmarksArray objectAtIndex:indexPath.row];
return cell;
}
- (void)dealloc {
[bookmarksArray release];
[super dealloc];
}
PERFORMING THE IBACTION FROM ANOTHER VIEW CONTROLLER
Header File
-(IBAction) pushChap01Bookmark:(id)sender;
Implementation File
-(IBAction) pushChap01Bookmark:(id)sender{
DissertationAppDelegate *appDelegate = (DissertationAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.array = [[NSMutableArray alloc] init];
[appDelegate.array addObject:@"THIS IS WHAT I WANT TO ADD"];
[self.navigationController pushViewController:bookmarksViewController animated:YES];
bookmarksViewController.title = @"Bookmarks";
}
Okkkkkkkkk.... So when you push the button I wanted it to add to the array in the app delegate and push the BookmarksViewController onto the navigation stack, and update the table. It does everything except for adding the object to the array.
If there is anyone out there who knows whats wrong then can you please help me out. I will appreciate it very much.
Thank you
You do realize that you're creating a new array object each time the IBAction is being called, retaining it twice without ever releasing it?
This will create a memory leak, but more importantly it will replace the whole array with a new one (never releasing the old one) each time you just want to add something. So you're actually not adding something, rather you're creating an array containing one object.
An action method is a bad place to initialize something like your array. Move the init code to the applicationDidFinishLaunching method or some other sane place, and don't forget to release it after you assign it to your property using the (retaining) accessor.
Edit: You're actually doing the init stuff in applicationDidFinishLaunching, however you're not assigning the resulting array to your appdelegates property, to the effect that it will be lost. Assign it to your property and remove the assignment in your IBAction, that should help.
Edit2: My bad again, you're actually assigning the array to your ivar, not using the accessor though. If the first few elements of your array are being displayed correctly and they remain in the tableview after you pushed the button, then your IBAction propably is not being called or your tableview doesn't reload. Your code should in effect remove all entries, replacing them with just one new entry. Put a NSLog into your IBAction to check whether it's being called, if not, check your connections. If so, check whether the tableview is actually reloading.
Edit3 (in response to your comment): Try adding the following line to your IBAction right after you add the new string..:
NSLog(@"The array contains %i objects.", [[appDelegate array] count]);
This should output to the console how many objects your array contains - if it does, and if the number increases each time you press the button, then something is wrong with your table reloading the data. I suspect that the way you "transport" the data to your bookmarksviewcontroller may be the cause of your problem - you're loading the appdelegates arrays content from disk only within viewdidload into your bookmarksarray. If viewdidload isn't called again, then the data in bookmarksarray won't be refreshed either. Try to re-read the file in viewWillAppear (or some other method that will be called before the tableview reloads). I strongly suggest that you find another way to store your data - your approach is prone for all sorts of errors. Try to get into NSUserdefaults oder Core Data instead. For testing purposes, however, try to replace this line
cell.textLabel.text = [bookmarksArray objectAtIndex:indexPath.row];
of your cellForRow... code with the following code:
DissertationAppDelegate *appDelegate = (DissertationAppDelegate *)[[UIApplication sharedApplication] delegate];
[[cell textLabel] setText:[[appDelegate array] objectAtIndex:indexPath.row]];
Let me know, what happens.
In pushChap01Bookmark you do this:
appDelegate.array = [[NSMutableArray alloc] init];
which recreates array in appDelegate (so it has again 0 items). Instead do it only if it's nil:
DissertationAppDelegate *appDelegate = (DissertationAppDelegate *)[[UIApplication sharedApplication] delegate];
if(appDelegate.array == nil) {
appDelegate.array = [[NSMutableArray alloc] init];
}
[appDelegate.array addObject:@"THIS IS WHAT I WANT TO ADD"];
//here save that appDelegate.array to file
[appDelegate saveArray];
Also create new saveArray method (you can use it again somewhere else) to save that array to file:
- (void)saveArray {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:@"%@/arraySaveFile", documentsDirectory];
[self.array writeToFile:fullFileName atomically:NO];
}
精彩评论