In want to delete rows from my UITableView. The UITableview gets it data from a plist. So when i delete a row i tell the app to delete the corresponding item in the plist (in this case a dictionary. One item of the dictionary (Name) is the title of the UITableViewCell, so the plist looks like so:
Dictionary
KEY(Name)
ITEM
KEY(Description)
ITEM
Dictionary
KEY(name)
....
)
And i use the following code to delete the rows, it works fine, apart from the very first row. The app crashes when i try to delete the first row, i have no idea why.
int g = indexPath.row;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.plist"];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
[array removeObjectAtIndex:g];
[array writeToFile:path atomically:YES];
EXC_BAD_ACCESS usually means that the program tried to use an object that had already been deallocated.
I doubt that such object could be array, since it has just been allocated when you try and remove its 0-th element. You could easily check this by adding an NSLog trace like here:
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(#"Array count: %d", [array count]);
[array removeObjectAtIndex:g];
In general, to determine which object could be, my suggestion is enable NSZombies. You can do that by running the app using the "Zombies" performance tool, or setting an environment variable.
You will get a much more descriptive error message that will also identify the type of object that you tried to access.
Related
I know this has been asked before, but there is no answer that I have found useful.
First off here is my code
// load the .csv file with all information about the track
NSError *error;
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"csv" inDirectory:nil];
NSString *datastring1 = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:&error];
NSArray *datarow = [datastring1 componentsSeparatedByString:#"\r"];
//fill arrays with the values from .csv file
NSArray *data_seg = [datarow objectAtIndex:0]; //segment number
NSArray *data_slength = [datarow objectAtIndex:1]; //strait length
NSArray *data_slope = [datarow objectAtIndex:2]; //slope
NSArray *data_cradius = [datarow objectAtIndex:3]; //circle radius
NSArray *data_cangle = [datarow objectAtIndex:4]; //circle angle
NSLog(#"%i", [data_seg count]);
Okay, so there is the code, and I read that is has something to do with autorelease, but I was not able to add a retain like NSArray *data_seg = [[datarow objectAtIndex:0] retain]
When I run the code, I get [__NSCFString count]: unrecognized selector sent to instance 0x9d1ad50
Any help is appreciated, I'm not good at programming, and I am very new.
componentsSeparatedByString method returns an NSArray of NSString. Every item that you extract from datarow array is an NSString and an NSString doesn't respond to 'count'. Your code starting at //fill arrays is incorrect. Every objectAtIndex call will return an NSString*.
This is another way of saying that the datatype for data_seg is NSString* (not NSArray*).
With the corrected code snippet, the problem is because data_seg is a string, and -count is not a method of NSString. It seems you think data_seg is an NSArray.
Look at the documentation for -[NSString componentsSeparatedByString:] and see what it returns -- strings! So you get back an array of strings. So what you want is:
NSString *data_seg = [datarow objectAtIndex:0]; //segment number
NSLog(#"my segment number is: %#", data_seg);
I am trying to read and I also need to write to a plist.
So far I am trying to simply read the contents in.
Here is my appSettings.plist:
NSBundle* bundle = [NSBundle mainBundle];
NSString* plistPath = [bundle pathForResource:#"appSettings" ofType:#"plist"];
NSDictionary *tmp = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
I tried to do this:
NSArray *mruItems = [[NSArray alloc] initWithArray:[tmp objectForKey:#"lastSearches"]];
But it throws an error. A check I did on the [tmp objectForKey:#"lastSearches"] type revealed this is not an NSArray...
How can I read the contents into my NSArray?
Thanks!
(I would love to have some info on writing too)
If you look at the screenshot above you see that it's pretty clear that "lastSearches" is a Dictionary, not a list. You can try to switch the type there to a Array type instead and it should work for you.
Another solution would be to iterate over the keys in that dictionary:
NSDictionary *lastSearches = [tmp objectForKey:#"lastSearches"];
for (NSString *key in lastSearches.allKeys)
{
NSString *value = [lastSearches objectForKey:key];
}
Note that this would not be in order, and you probably would have to sort before iterating over it.
Indeed it's not an array but a dictionary (look at your image).
I'm splitting a string by ';', but want to specifically grab the first and second element.
I know with PHP it's just simply $array[0], just can't find anything for this for Objective-C
NSArray *tempArray = [returnString componentsSeparatedByString:#";"];
So here I have assigned my array, how can I go about getting the first and second element?
Its just simply [array objectAtIndex:0] in Objective-C ;-)
Starting with XCode 4.5 (and Clang 3.3), you may use Objective-C Literals:
NSString *tmpString1 = tempArray[1];
NSString *tmpString = [tempArray objectAtIndex:0];
NSLog(#"String at index 0 = %#", tmpString);
NSString *tmpString1 = [tempArray objectAtIndex:1];
NSLog(#"String at index 1 = %#", tmpString1);
You may also wish to do an IF statement to check tmpArray actually contains objects in before attempting to grab its value...
e.g.
if ([tempArray count] >= 2) {
// do the above...
}
I am trying to save and read back some application settings stored as NSStrings in an iPhone app and have been having some trouble.
The code to save looks like:
NSMutableArray *array = [[NSMutableArray alloc] init];
[array addObject:accountID];
...
[array writeToFile:[self dataFilePath] atomically:YES];
[array release];
And the code to read looks like (accountID is an NSString*):
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
accountID = [array objectAtIndex:0];
...
[array release];
NSLog(#"Loading settings for: %#", accountID);
The read code throws an exception because after the array is released the accountID variable also appears to have been released (moving the NSLog call before releasing the array works fine). So I'm guessing that I'm creating a reference to the array instead of pulling out the actual string contained in the array. I tried several things to create new strings using the array contents but haven't had any luck.
You guess is on the right lines although you have a reference to the 0th element of the array not the array. The array consists of pointers to NSString objects. The Strings will get get released when yhe array is released.
You need to retain the element you are using e/g/
NSArray *array = [[NSArray alloc] initWithContentsOfFile:filePath];
NSString* accountID = [[array objectAtIndex:0]retain];
...
[array release];
NSLog(#"Loading settings for: %#", accountID);
When you release the array the reference to the accountID will also be released. You need to retain it.
accountID = [[array objectAtIndex:0] retain];
Then obviously at some point you need to release it.
try [accountID retain] before you release the array
How to print a array element at particular index in Objective-C? My code looks like this:
NSString *String=[NSString StringWithContentsOFFile:#"/User/Home/myFile.doc"];
NSString *separator = #"\n";
NSArray *array = [String componetntsSeparatedByString:separator];
NSLog(#"%#",array);
I'm able to print the full contents of an array at once, but I want to assign the element at each index into a string, like...
str1=array[0];
str2=array[1];
str3=array[0];...this continues
How do I do this?
You want the objectAtIndex: method. Example:
NSString *str1 = [array objectAtIndex:0];
NSString *str2 = [array objectAtIndex:1];
NSString *str3 = [array objectAtIndex:2];
From the documentation:
objectAtIndex:
Returns the object located at index.
- (id)objectAtIndex:(NSUInteger)index
Parameters
index
An index within the bounds of the receiver.
Return Value
The object located at index.
Discussion
If index is beyond the end of the array (that is, if index is greater than or equal to the value returned by count), an NSRangeException is raised.
if this is only for debugging, you could try using po <> in the gdb.
As of clang version 3.3, you can use the [index] notation, so
NSString *str1 = array[0];
would work now. See here for details.