NSMutableArray empty after leaving View - iphone

I have a Mutable Array and I fill it with some strings. But when I leave the view (Navigation Controller) and reopen it, the Array is empty. My Mutable Array gets emptied, everytime I leave the view.
if([name_Recipe isEqualToString:#""])
{
NSLog(#"Nothing");
}
else
{
[favoritesArrayDetail addObject:name_Recipe];
NSLog(#"%#", [NSString stringWithFormat:#"%#", favoritesArrayDetail]);
}

This is because when you leave the view, the view controller is being released along with all of its member variables. If you want to still be able to access the array, you need yo declare it somewhere else, or make it static.
EDIT: Since viewDidLoad is called every time you go back to the view, it is resetting the array back to an empty one because of [NSMutableArray new]. You want to only call that line of code when the array has not yet been created.
For example, you could do:
if (!favoritesArrayDetail) //Only do this code if the array is nil.
favoritesArrayDetail = [NSMutableArray new];

Declare your array as a property.
#property (nonatomic, copy) NSMutableArray *favoritesArrayDetail;
And in viewDidLoad:
if (!favoritesArrayDetail)
{
favoritesArrayDetail = [NSMutableArray new];
}

Related

NSMutable array adding entries?

I am pretty new to objective-c and I am creating an app where records are held. I have tried to make an adding method when I click a save button though it doesn't save the data when you press the button or if it does it doesn't display it. The data is being shown in a tableView
here is the code for the save button:
-(void)savePatient:(id)sender {
LSAppDelegate *delegate = (LSAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *patients = delegate.patients;
UITextField *firstnameEntry = (UITextField *)[firstNameCell viewWithTag:777];
UITextField *surnameEntry = (UITextField *)[surnameNameCell viewWithTag:777];
UITextField *dobEntry = (UITextField *)[dobDateCell viewWithTag:777];
UITextField *homeNumberEntry = (UITextField *)[homeNumberCell viewWithTag:777];
UITextField *mobileNumberEntry = (UITextField *)[mobileNumberCell viewWithTag:777];
UITextField *emailAddressEntry = (UITextField *)[emailAddressCell viewWithTag:777];
UITextView *addressEntry = (UITextView *)[addressCell viewWithTag:777];
if (firstnameEntry.text.length > 0) {
Patient *newPatient = [[Patient alloc] init];
newPatient.patientName = firstnameEntry.text;
newPatient.patientSurname = surnameEntry.text;
newPatient.patientDoB = dobEntry.text;
newPatient.patientHomeNumber = homeNumberEntry.text;
newPatient.patientMobileNumber = mobileNumberEntry.text;
newPatient.patientEmail = emailAddressEntry.text;
newPatient.patientAddress = addressEntry.text;
newPatient.patientPicture = nil;
[patients addObject:newPatient];
LSViewController *viewController = delegate.viewController;
[viewController.tableView reloadData];
}
[delegate.navController popViewControllerAnimated:YES];
}
I've found that the issue is here
if (firstnameEntry.text.length > 0) {
please say if you want any more code
Thanks in advance
You need to make sure that your delegate has the proper retain type and not copy as copy in the property returns an array and not an NSMutableArray.
Although your problem of loading data is probably a simple issue of not allocing/initing your array. It would be better to move your patients array to your local class.
Move this property from your delegate to your class.
#property (nonatomic, retain) NSMutableArray *patients;
Do not use copy and do not use NSArray. Also, you need to make sure that somewhere you are instantiating the mutable array. Preferably in the viewDidLoad function.
In your class, somewhere before this viewcontroller is created be sure you create the array.
self.patients = [[NSMutableArray alloc] init];
This assumes you're using ARC. If you're not using ARC be sure to release the array in the dealloc method.
Usually if data isn't coming across it's b/c your array is nil or an NSArray and not NSMutableArray.
I would also add breakpoints in your method above and make sure that your tableView is not nil and that your array is not nil.
Are you sure that [viewController.tableView reloadData]; actually get
executed, i seriously doubt it since you're on a different viewController,
you could try to put the reloatData statement on the viewDidAppear event of your table
controller view after you pop from the editing viewController.

Automatically update UITableView when Array changes

I have a View Controller containing a UITableView that used an NSMutableArray to determine its content via the usual UITableViewDelegate and UITableViewDataSource methods.
In the past I have used NSFetchedResults controller to update the TableView as the result of its query results changing. In this case I would like to update the UITableView appropriately as items are added to/removed from the array.
How should I handle this? Should I wrap the NSMutableArray in a model class with addItem/removeItem methods which use delegation or Notification to trigger reloadData on the UITableView? Or is there a more elegant solution?
There are maximum ~20 items in the array so performance isn't so much of an issue.
Caveat: Non ARC example
You could set up the array which your tableview uses as a property
//.h
..... {
NSArray* array_;
}
#property (nonatomic, retain) NSArray* array;
//.m
Synthesize the array
#synthesize array = array_;
We are interested when array changes so override the setter method
-(void)setArray:(NSArray*)array {
if (array_ != array) {
[array_ release];
array_ = [array retain];
[self.tableview reloadData];
}
}
Then whenever you modify your tableview data, array: At the end of modifying the data.
self.array = newArray;
As it's a property external classes / views will be able to modify array and the table will update.
It seems that NSArrayController is what I want, however it is not available in iOS, so it looks like KVO is my best bet.

Problem with NSMutableArray

I declared a NSMutable array and assigned some values to it.
.h
NSMutableArray *imageDetailsFromCategory;
#property (nonatomic, retain) NSMutableArray *imageDetailsFromCategory;
.m
#synthesise imageDetailsFromCategory
in ViewDidLoad:
imageDetailsFromCategory = [[NSMutableArray alloc]init];
//assigning object to Array..working fine.showing two images.
imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString];
Now my app is loading... I am doing some UI changes with the array. However I want to pass this array on another button click to another class. But when click event is triggered the array shows 0x76779e0"{(int)$VAR Count} like this in the same class I declared the arry. I can't get the array count after the button click.
Can any one tell me how can I access my array. What is the problem?
The method [self getImageDetailsFromCategory:generatedString]; I think returns a autoreleased array. Try using the proper setter for retaining it, like
self.imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString];
You are overriding your imageDetailsFromCategory variable that you alloc'd in the first line with your second line.
So imageDetailsFromCategory = [[NSMutableArray alloc] init] creates a mutable array… but imageDetailsFromCategory = [self getImageDetailsFromCategory:generatedString]; replaces the previously alloced mutable array with a brand new object.
THat's as if you did int i=5; then i = [self someMethod];: the value 5 would be lost.

iOS - resetting NSMutable Array causes crash

I have an NSMutableArray I'm trying to reload after an async call. The first time it loads like this:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
After the user does some interaction, the same line will be reached to reload the NSMutableArray. This causes the crash
Header file has:
#interface...
NSMutableArray *sessionProcList;
... }
#property (nonatomic, retain) NSMutableArray *sessionProcList;
Say you do:
NSMutableArray *a = [NSMutableArray arrayWithObject: [[NSObject alloc] init]];
NSObject *o = [a objectAtIndex: 0];
[a removeAllObjects];
[o description]; // *BOOM*
The above will [generally -- sometimes not but only by coincidence] crash because o has been deallocated by the time the description method is invoked.
If you have a reference to an object in an array, but have not retained said reference, then said object may be deallocated out from under you when you empty the array.
(And nonatomic vs. atomic is irrelevant.)
If I had to guess, I would say that elements in that array are being referenced from somewhere else. Resetting the array causes the items using the references to crash.
I would check your application for other variables, properties, or UI elements using those variables that have not been release before resetting it.
Because arrayWithArray is a convenience method it gets initialised with an autorelease flag.
You haven't mentioned what the crash / error message is but I am guessing your NSMutableArray is getting released before your second iteraction with it starts.
Try and retain the array for however long you need it with:
self.sessionProcList = [NSMutableArray arrayWithArray:[result records]];
[sessionProcList retain];
And then release it when you're done with it:
[sessionProcList release];
I hope it helps.
Rog

NSMutableArrays

I have an NSMutableArray as a member variable for a class.
In the .h file:
#interface bleh {
NSMutableArray *list;
}
#property (readonly, assign) NSMutableArray *list;
#end
In the .m file:
#implementation bleh
#synthesize list;
-(void)init;
{
list = [NSMutableArray arrayWithCapacity:30];
}
#end
Now, I'm not really an objective-C programmer, so maybe I'm missing some of the nuances, but when I do the following:
NSMutableString *listItem = [NSMutableString stringWithString:#"Foobar"];
[list addObject:listItem];
I'm getting strange behavior. Namely, I'm using this to keep a list of files that I eventually want to attach to an email and then open the picker. I'm getting a SIGABRT, and upon debugging, I find out that whenever I operate on list, I'm getting nothing. addObject messages don't increase the size of the NSMutableArray at all.
Am I missing something? Can someone show me a full implementation of setting up an NSMutableArray to be manipulated within a class in Objective C?
Thanks.
PS - Assume that I'm smart enough to put the manipulations of the NSMutableArray inside of a member function for the class containing the member variable.
in the latest release of the SDK arrayWithCapacity is bad practice.
but in your code you creating a array that no one is owner , clam your array properly.
don't forget initialize your array
NSMutableArray *array = [[NSMutableArray alloc] init];
fix the (readonly,assign),
How are you actually creating your array? Is it possible that it's being autoreleased and going away? Remember, if you create it with a convenience method (like array or something) you need to retain it.
You're creating the array with arrayWithCapacity:, which returns an array you don't own, and you're never claiming ownership over it. Use a property accessor to retain the array:
self.list = [NSMutableArray arrayWithCapacity:30];
I would recommend reading the Cocoa memory management docs. Once you know the rules in there, it will be clear what to do in this sort of situation. They're not very hard, but they are very necessary if you're going to be programming Cocoa.
Your list variable has been auto-released and de-allocated, therefore your program crashes when you try to access it.
There are two ways to create objects in Cocoa:
NSMutableArray* array1 = [[NSMutableArray alloc] initWithCapacity:10];
NSMutableArray* array2 = [NSMutableArray arrayWithCapacity:10];
array1 was created using alloc+init, therefore you own it. It will stick around until you release it.
array2 was not created using alloc+init, therefore you do not own it. You're not responsible for releasing it, but it will go away on its own. You must retain array2 if you want it to stick around.
Your list property declaration is keeping you from properly retaining the NSMutableArray. By calling arrayWithCapacity you're effectively putting the array in an autorelease pool, which means it could be deallocated at any time if no object interested in keeping it around. While you are, the way you have things declared doesn't reflect that:
#property (readonly, assign) NSMutableArray *list;
The above declaration simply sets this pointer to be a copy of another pointer - it does no memory management for you. Instead it should read:
#property (readonly, retain) NSMutableArray *list;
... and you should assign the list like so:
self.list = [NSMutableArray arrayWithCapacity:64];
Because you specify the retain attribute for the property, whenever it is assigned a new value the retain message will be sent to that new value, communicating to the memory manager that you don't want this object deallocated. In order to bring this full circle, you'll need to release the object when you containing class is deallocated:
- (void)dealloc
{
[list release];
[super dealloc];
}
Are you initializing your list properly? Ie do you have something like the following in your code?
list = [[NSMutableArray alloc] init];
Problem ehre (assuming you initing your array properly) could be that #"Foobar" assings an NSString not an NSMutableString so its failing because if distinct types you should do
NSMutableString *listItem = [NSMutableString stringWithString:#"Foobar"];
[list addObject:listItem];
or
NSString *listItem =#"FooBar";
[list addObject:listItem];
It doesn't look as though you've actually initialized the NSMutableArray.
In the init event of the object, just say
[self setList:[[NSMutableArray alloc] initWithCapacity:10]]];
(I would just say init, but I don't remember if that works. It doesn't matter what capacity you start with)
Before actually allocating the array, the variable "list" will have a value of nil.