3 lines of code, one causes EXC_BAD_ACCESS - ios

I have an array that I want to populate with a dictionary, however I get EXC_BAD_ACCESS when I try to view the pickerView that is populated with the array. One of these 3 lines of code causes it.
paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) copy];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"];
Full Code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory stringByAppendingPathComponent:#"fullArray.plist"];
dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
array = [dictionary allKeys];
[pickerView selectRow:0 inComponent:0 animated:YES];
[pickerView reloadAllComponents];
}

Maybe the NSArray returned by NSSearchPathForDirectoriesInDomains is becoming a Zombie. You could try getting a copy of it like this:
NSArray *paths = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) copy];

Looks like, with this line, you're trying to save a value into an ivar named "arrays":
array = [dictionary allKeys];
But that's not going to work (unless it's and ARC project, which you say it isn't).
You need to retain that value. Make array a property that's retained (or copied). Or (not quite as good) retain it yourself:
[array autorelease]; // Don't skip this, or it may leak.
array = [[dictionary allKeys] retain];

Related

NSArray Getting Out Of Order

I use a PLIST to populate a TableView in my app. I want the TableView to be in order of how items were added, due to needing a good way to edit it later on, so the indexPath.row will match up with the indexPath of the PLIST. I get the TableView populated by going from the PLIST to NSDictionary to NSArray. The issue is that the TableView keeps listing everything in alphabetical order and not the order it was listed
NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:self.selectedCountry];
_plist = [NSMutableDictionary dictionaryWithContentsOfFile: plistPath];
_content = [_plist allKeys];

Trying to load a saved NSMutableArray

This is the code I'm using to save an NSMutableArray "names" (after the user presses a save button), and I think it's working without problems, but I'm not sure what the corresponding code would be to then load my array when I reopen my app. Any help would be greatly appreciated!
- (IBAction)save:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [NSString stringWithFormat:#"%#/temporaryArray", docDir];
[NSKeyedArchiver archiveRootObject:names toFile:fullFileName];
}
Well, you're halfway there. You've figured out how to archive the object. The question is, how do you unarchive it? As I explained in my comment, this is done with the very aptly named NSKeyedUnarchiver class.
Let's begin with a code sample:
#try {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *defaultPath = [docDir stringByAppendingPathComponent:#"temporaryArray"];.
self.yourArray = [NSKeyedUnarchiver unarchiveObjectWithFile: defaultPath];
if (!self.yourArray) {
NSLog(#"Error!");
} else {
// Success!
}
} #catch (NSException *exception) {
NSLog(#"Some error happened: %#", exception);
}
The NSKeyedUnarchiver class takes a path to a file containing the content archived by NSKeyedArchiver. It will then read this file and return the "root" object -- the object that you told NSKeyedArchiver to archive. It's that simple. (You should, of course, include error handling, which I gave a brief example of above.)
If you want another resource, you can read this great introductory article by the famous Mattt Thompson, which gives a good explanation of the concepts behind the class.
Hope this helps.
If your array's contents are all property list objects (NSString, NSData, NSArray, or NSDictionary objects) then you can do saving and reading in a way other than using NSKeyedArchiever/NSKeyedUnarchiever:
- (IBAction)save:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [docDir stringByAppendingPathComponent:#"temporaryArray"];
[names writeToFile:fullFileName atomically:YES];
}
- (NSMutableArray*)readNames
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullFileName = [docDir stringByAppendingPathComponent:#"temporaryArray"];
return [NSMutableArray arrayWithContentsOfFile:fullFileName];
}
- (IBAction)save:(id)sender
{
// check for previous data persistancy.
NSArray *arrData = [[NSUserDefaults standardDefaults]objectforkey:#"Paths"];
if(arrData == nil)
{
// Maintain your old data and update it in new one to store the same.
NSMutableArray *arrTempData = [NSMutableArray arrayWithArray:arrData];
//Add Some data to old array based on your bussiness logic.
[arrTempData add object:#"some data"];
// Update in User Defaults
[[NSUserDefaults standardDefaults]setobject:[NSArray arrayWithArray:arrTempData] forkey:#"Paths"];
}
}
Somewhere in your code,put below code to get the data,
NSArray *arrSavedData = [[NSUserDefaults standardDefaults] objectforkey:#"Paths"];

Reading and Writing NSMutableArray to iPhone not working (Works on iOS Simulator)

In an app I am working on I want to have an NSMutableArray (called pathsArray) that I can read from a file in the app's directory, be able create an instance of that array that I can add objects to and/or remove objects from, and then I want to write it back to the file. I have a UILabel that shows the number of contents in this array. My problem: my code below works fine on Xcode's iOS Simulator but when I try to run the app on my actual iPhone the data isn't saved. I know there are a lot of questions on here related to this issue but i can't seem to see what I am doing wrong. Any help would be greatly appreciated.
- (void) loadArrayContents {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingString:#"theArray"];
//Objects contained in an array returned by 'initWithContentsOfFile' are immutable even if the array is mutable
NSArray* contentsArray = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
pathsArray = [[NSMutableArray alloc] initWithArray:contentsArray];
}
and...
- (void) saveArrayContents {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
NSString* filePath = [documentsDirectory stringByAppendingString:#"theArray"];
[pathsArray writeToFile:filePath atomically:YES]);
}
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"theArray"];
should solve the issue. The problem with
NSString *filePath = [documentsDirectory stringByAppendingString:#"theArray"];
is that it does not add / in the file path.

iOS Pragmatically Create Plist with 15 Array Objects

I hope someone can help, before asking we're using Plist to slimline the whole app. I am creating a plist when somebody selects a player. However what I want to do is create a plist with 15 blank array objects, this way I can just replace and edit as the user goes.
Any help would be appreciated. Thanks!
To create plist with 15 arrays you can use:
NSMutableArray * mainArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 15; i++)
{
NSArray *array = [NSArray alloc] init];
[mainArray addObject:array];
}
[self saveToFile:mainArray];
Method for saving:
- (void)saveToFile:(NSArray*)ar
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.plist"];
[ar writeToFile:path atomically:YES];
}
Hope you find it useful.

my Plist not updating or I can't find where to look

I have an existing PList in my project called "Account.plist" ... it loads my initial Tableview ... and it sends said data to the detail view. I created another detail view called AddViewcontroller ... I have 5 blank text fields ... I created a button and the button action executes this code below: but I cannot find either an update to my "Account.plist" or where a new copy of my "Accounts.plist" in my Library folder for the project. any assistance would be appreciated. thank you in advance.
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:AcctName.text];
[array addObject:AcctNum.text];
[array addObject:DayDue.text];
[array addObject:paymnt.text];
[array addObject:remBalance.text];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *plistPath = [documentPath stringByAppendingPathComponent:#"Accounts.plist"];
[array writeToFile:plistPath atomically: true];

Resources