Get & Edit NSMutableArray from different class file - objective-c

I am trying to access and change a array from a different class file. When using a NSLog, I get a result of (null). Below is my code:
RootViewController.h
NSMutableArray *listOfItems;
#property (nonatomic, retain) NSMutableArray *listOfItems;
RootViewController.m
#synthesize listOfItems;
listOfItems = [[NSMutableArray alloc] init];
[listOfItems addObject:#"One"];
[listOfItems addObject:#"Two"];
[listOfItems addObject:#"Three"];
SecondViewController.m
RootViewController *test = [[RootViewController alloc] init];
NSLog(#"Results: %#", test.listOfItems);
I get the following results in my console: Results: (null)
Thanks in advance,
Coulton
P.S. Obviously I have left out a bunch of code. I just tried to make it easier to read. If you need to see anything else, I would be more than happy to post more. Just ask
EDIT #1:
I am getting hundreds of NSLog Messages that look something like this:
*** __NSAutoreleaseNoPool(): Object 0x4e39020 of class __NSArrayI autoreleased with no pool in place - just leaking
And here's my init code:
- (id) init {
//NSLog(#"%#", theUserID);
// Set up database connection
NSString *myDB = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.db"];
database = [[Sqlite alloc] init];
[database open:myDB];
//Initialize the array.
listOfItems = [[NSMutableArray alloc] init];
// Add to array to display in the tableView
NSArray *listOfItemsTwo = [database executeQuery:#"SELECT * FROM albums"];
for (NSDictionary *rowone in listOfItemsTwo) {
NSString *getName = [rowone valueForKey:#"name"];
if (getName != NULL) {
[listOfItems addObject:getName];
[getName release];
}
}
return self;
}

I guess you reversed RootViewController.m and RootViewController.h snippets right?
Are you sure that the
listOfItems = [[NSMutableArray alloc] init];
gets called? Maybe you can put a breakpoint there.
EDIT: Order of RootViewController.m and RootViewController.h has been fixed in the question. It's not clear from the question where the above line is in the code. That's a important piece of information.
EDIT2: Example of init method.
#implementation RootViewController
- (id) init
{
listOfItems = [[NSMutableArray alloc] init];
[listOfItems addObject:#"One"];
return self;
}
#end

Related

nsmutable array not saving values

My array is not saving the values I put in it...
I am defining my nsmutablearray *arrayClientList in .h file
#interface StartupTableViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#property NSMutableArray *arrayClientList;
#property BOOL boolAddToClient;
//#property (strong, nonatomic) NSMutableArray *arrayAddClient;
#end
in .m file I am initializing like so
- (void)viewDidLoad {
[super viewDidLoad];
//initialize variables
self.arrayClientList = [[NSMutableArray alloc] init];
arraySelectedInformation = [[NSMutableArray alloc] init];
self.boolAddToClient = NO;
NSString *tstring = #"hello";
[self.arrayClientList addObject:tstring];
but then once I get to another method in this same class... the array is nil again. I must be doing something stupid for the array not to hold the values
-(void)viewDidAppear:(BOOL)animated{
//NSLog(#"appeared");
if (self.boolAddToClient) {
NSLog(#"add client to list");
self.boolAddToClient = NO;
[self.tableView reloadData];
}
else{
NSLog(#"startup");
}
}
I am trying to use it in another class
- (IBAction)buttonSubmit:(id)sender {
NSString *userDescription = [[NSString alloc] init];
NSString *userUsername = [[NSString alloc] init];
NSString *userPassword = [[NSString alloc] init];
userDescription = self.textfieldDescription.text;
userUsername = self.textfieldUserID.text;
userPassword = self.textfieldPW.text;
//check to make sure user filled out all fields
if (![userDescription isEqual:#""] && ![userUsername isEqual:#""] && ![userPassword isEqual: #""]){
NSLog(#"correct");
NSArray *arrayVC = self.navigationController.viewControllers;
StartupTableViewController *parentViewController = [arrayVC objectAtIndex:0];
parentViewController.boolAddToClient = YES;
NSMutableArray *arrayNewObjects = [[NSMutableArray alloc] initWithObjects:userDescription, userUsername, userPassword, nil];
NSMutableArray *tarray = parentViewController.arrayClientList;
[tarray addObject:arrayNewObjects];
[parentViewController.arrayClientList addObject:arrayNewObjects];
[self.navigationController popViewControllerAnimated:YES];
}
else{
NSLog(#"something missing");
}
}
Since I can't comment without rep, I must try with answer.
Try this:
In ViewDidLoad do alloc init with Strings you create in implementation and also change if block to this:
#implementation
{
NSString *userDescription;
NSString *userUsername;
NSString *userPassword;
}
-(void)viewDidLoad {
[super viewDidLoad];
NSString *userDescription = [[NSString alloc] init];
NSString *userUsername = [[NSString alloc] init];
NSString *userPassword = [[NSString alloc] init];
}
- (IBAction)buttonSubmit:(id)sender {
if (self.textfieldDescription.text.lenght != 0 && self.textfieldUserID.text.lenght != 0 && self.textfieldPW.text.lenght != 0) {
userDescription = self.textfieldDescription.text;
userUsername = self.textfieldUserID.text;
userPassword = self.textfieldPW.text;
....... and the rest
}
Please comment if it's not working, and I also think that you're not passing the informations right. Try searching an answer on how to pass arrays between TableViewControllers. Good Luck!

EXC_BAD_ACCESS when I work with arrays

I always have error when working with arrays (non ARC code).
My code:
#implementation InfoController
NSMutableArray *lbCityArray;
NSMutableArray *lbTimeArray;
NSMutableArray *lbCameInArray;
NSMutableArray *lbCameOutArray;
NSMutableArray *lbInArray;
NSMutableArray *lbOutArray;
in ViewDidLoad I do something
- (void)viewDidLoad
{
[super viewDidLoad];
lbCityArray = [[NSMutableArray alloc] initWithCapacity:1];
lbTimeArray = [[NSMutableArray alloc] initWithCapacity:1];
lbCameInArray = [[NSMutableArray alloc] initWithCapacity:1];
lbCameOutArray = [[NSMutableArray alloc] initWithCapacity:1];
lbInArray = [[NSMutableArray alloc] initWithCapacity:1];
lbOutArray = [[NSMutableArray alloc] initWithCapacity:1];
//—add some values to arrays
NSString *City = #"London";
[lbCityArray addObject:City];
//—————————————-----------------------//
}
and always when I click Back button app crash with EXC_BAD_ACCESS. If I comment adding values to array all work, Back button don't crash app. I read if you use non ARC code you must manually release in dealloc.
I add to dealloc
[_InfoTableView release];
[lbCityArray release];
[lbTimeArray release];
[lbCameInArray release];
[lbCameOutArray release];
[lbInArray release];
[lbOutArray release];
[super dealloc];
and nothing changes, app still crash. Where can be problem ?
Solution - I move to ARC and all problems gone. Thanks.
It would help a lot if you made your variables into instance variables instead of global variables.
Change this:
#implementation InfoController
NSMutableArray *lbCityArray;
NSMutableArray *lbTimeArray;
NSMutableArray *lbCameInArray;
NSMutableArray *lbCameOutArray;
NSMutableArray *lbInArray;
NSMutableArray *lbOutArray;
into:
#implementation InfoController {
NSMutableArray *lbCityArray;
NSMutableArray *lbTimeArray;
NSMutableArray *lbCameInArray;
NSMutableArray *lbCameOutArray;
NSMutableArray *lbInArray;
NSMutableArray *lbOutArray;
}
Without the curly braces you are actually creating global variables, not instance variables.

issue adding NSMutablearray to other NSMutablearray? [duplicate]

This question already has answers here:
Cannot add items to an NSMutableArray ivar
(4 answers)
Closed 8 years ago.
I'm trying to add NSMutableArray to other NSMutableArray, a mutable array set as instance ivar, but I allways got the array arrayPlayoff empty. Other thing that I have detected, is that when debugging in the attached method, local variables are not shown in the debugger variables section, even selecting "local" option.
-(void)loadGamesPlayoffs{
NSMutableArray *eli1 = [[NSMutableArray alloc] init];
NSMutableArray *eli2 =[[NSMutableArray alloc] init];
NSMutableArray *eli3 = [[NSMutableArray alloc] init];
NSMutableArray *eli4 = [[NSMutableArray alloc] init];
for (NSDictionary *eliminatoria in copaReyArray){
int eli = [[eliminatoria valueForKey:#"eliminatoria"]integerValue];
NSLog(#"eli %d", eli);
if (eli==1){
[eli1 addObject:eliminatoria];
} else if (eli==2){
[eli2 addObject:eliminatoria];
}else if (eli==3){
[eli3 addObject:eliminatoria];
} else if (eli==4){
[eli4 addObject:eliminatoria];
}
}
[arrayPlayOff addObject:eli1];
[arrayPlayOff addObject:eli2];
[arrayPlayOff addObject:eli3];
[arrayPlayOff addObject:eli4];
}
many thanks
If arrayPlayOff is an Instance Variable you could use properties, your .h should look something like this:
#import <UIKit/UIKit.h>
#interface YourClassViewController : UIViewController{
NSMutableArray *arrayPlayOff;
//Some other variables
}
#property (nonatomic, retain) NSMutableArray *arrayPlayOff;
//Some other methods
#end
Then in your .m file you could use:
#implementation YourClassViewController
#synthesize arrayPlayOff;
- (NSMutableArray *)arrayPlayOff{
if(!arrayPlayOff){
arrayPlayOff = [[NSMutableArray alloc] init];
}
return arrayPlayOff;
}
//Your other methods
//Overwrite the dealloc function so you don't have any memory leaks
- (void)dealloc{
[arrayPlayOff release];
[super dealloc];
}
#end
Now you could access your variable as
self.arrayPlayOff
and this way you can be 100% sure that your variable is always initialized.
Your method could look like this (Also you should release your other NSMutableArrays since you are not using after adding them to the arrayPlayOff array):
-(void)loadGamesPlayoffs{
NSMutableArray *eli1 = [[NSMutableArray alloc] init];
NSMutableArray *eli2 =[[NSMutableArray alloc] init];
NSMutableArray *eli3 = [[NSMutableArray alloc] init];
NSMutableArray *eli4 = [[NSMutableArray alloc] init];
for (NSDictionary *eliminatoria in copaReyArray){
int eli = [[eliminatoria valueForKey:#"eliminatoria"]integerValue];
NSLog(#"eli %d", eli);
if (eli==1){
[eli1 addObject:eliminatoria];
} else if (eli==2){
[eli2 addObject:eliminatoria];
}else if (eli==3){
[eli3 addObject:eliminatoria];
} else if (eli==4){
[eli4 addObject:eliminatoria];
}
}
[self.arrayPlayOff addObject:eli1];
[self.arrayPlayOff addObject:eli2];
[self.arrayPlayOff addObject:eli3];
[self.arrayPlayOff addObject:eli4];
//Releasing the NSMutableArrays
[eli1 release];
[eli2 release];
[eli3 release];
[eli4 release];
}

NSMutableArray addObject in for loop - memory leak

i'm putting strings (which are filenames of files in a certain directory) into an NSMutableArray with a for loop:
h-file:
#import <Three20/Three20.h>
#interface AlbumController : TTThumbsViewController {
NSMutableArray *images;
}
#property (nonatomic, retain) NSMutableArray *images;
#end
m-file:
#import "AlbumController.h"
#import "PhotoSource.h"
#import "Photo.h"
#implementation AlbumController
#synthesize images;
-(void)createPhotos {
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundleRoot error:nil];
NSArray *onlyJPGs = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self ENDSWITH '.jpg'"]];
NSMutableArray *pics = [[onlyJPGs copy] autorelease];
if(!self.images) {
self.images = [[NSMutableArray alloc] init];
}
for(int i = 0; i < [onlyJPGs count]; i++)
{
//NSLog([pics objectAtIndex:i]);
NSString *ImgURL = [#"bundle://" stringByAppendingString:[pics objectAtIndex:i]];
Photo *photo = [[Photo alloc] initWithURL:ImgURL smallURL:ImgURL size:CGSizeMake(320, 212)];
[images addObject:photo];
[photo release];
}
}
-(void)viewDidLoad{
[self createPhotos]; // method to set up the photos array
self.photoSource = [[PhotoSource alloc]
initWithType:PhotoSourceNormal
title:#"Chili Pflanzen"
photos:images
photos2:nil
];
}
#end
i do not have any problem in the simulator but on my iPod...
Error message:
Data FOrmatters temporarily unavailable, will re-try after a 'continue'. (Unknown error loading shared library "/Developer/usr/lib/libXcodeDebuggerSupport.dylib")
thanks in advance
I think you should use mutableCopy and not copy on your pics array.
so instead of:
NSMutableArray *pics = [[onlyJPGs copy] autorelease];
you should use:
NSMutableArray *pics = [[onlyJPGs mutableCopy] autorelease];
More information about copy/mutablecopy in this question: Copy & mutableCopy?
Looks like the main issue is with
[images addObject:[[Photo alloc] initWithURL:ImgURL smallURL:ImgURL size:CGSizeMake(320, 212)]];
Here you are alloc'ing Photo but not releasing it. When you add an object to an array it increases the retain count for it.
Try changing it to
Photo *photo = [[Photo alloc] initWithURL:ImgURL smallURL:ImgURL size:CGSizeMake(320, 212)];
[images addObject:photo];
[photo release];
In addition ...
I'd change
self.images = [[[NSMutableArray alloc] init] autorelease];
to
if(!self.images) {
self.images = [[NSMutableArray alloc] init];
}
Otherwise there is the potential for a memory leak if it has already been initialized, as well as that you probably do not want it autoreleased;
Your NSMutableArray instance is autoreleased. You are assigning it to the images ivar. The fact that you have declared it as a retained property doesn't matter, because you aren't assigning it to the property. My guess is that you meant to assign to the property, and the crash is caused by the inadvertent deallocation.
Change:
images = [[[NSMutableArray alloc] init] autorelease];
...to:
self.images = [[[NSMutableArray alloc] init] autorelease];
...or:
images = [[NSMutableArray alloc] init];
Also note that your property is declared as NSArray when you are allocating an instance of NSMutableArray.
Also see the Memory Management Programming Guide.

Storing Sorted Arrays Causing EXC_BAD_ACCESS Error

Given a basic key/value array, I'm wanting to store two sorted arrays based on the original array: one array will be sorted by name, and the other by age.
The arrays seem to be sorting correctly when I output them to the log; however, when I try to access them elsewhere in the code, I'm receiving a EXC_BAD_ACCESS error.
Here's what I have so far:
// MyController.h
#interface MyController : UIViewController {
NSMutableArray *originalArray;
NSMutableArray *nameArray;
NSMutableArray *ageArray;
}
#property (nonatomic, retain) NSMutableArray *originalArray;
#property (nonatomic, retain) NSMutableArray *nameArray;
#property (nonatomic, retain) NSMutableArray *ageArray;
-(void)someRandomMethod;
#end
// MyController.m
#import "MyController.h"
#implementation MyController
#synthesize originalArray;
#synthesize nameArray;
#synthesize ageArray;
-(void)viewDidLoad {
// originalArray = (
// {
// "name" = "Sally";
// "age" = 18;
// },
// {
// "name" = "Chad";
// "age" = 26;
// },
// {
// "name" = "Carla";
// "age" = 24;
// },
// )
// sort by name
NSSortDescriptor *sortByNameDescriptor;
sortByNameDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"name"
ascending:NO] autorelease];
NSArray *sortByNameDescriptors = [NSArray arrayWithObject:sortByNameDescriptor];
nameArray = [originalArray sortedArrayUsingDescriptors:sortByNameDescriptors];
// sort by age
NSSortDescriptor *sortByAgeDescriptor;
sortByAgeDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"age"
ascending:NO] autorelease];
NSArray *sortAgeDescriptors = [NSArray arrayWithObject:sortByAgeDescriptor];
ageArray = [originalArray sortedArrayUsingDescriptors:sortByAgeDescriptors];
[super viewDidLoad];
}
-(void)someRandomMethod {
// whenever I try to access the sorted arrays, I receive the EXC_BAD_ACCESS error
[[nameArray objectAtIndex:0] valueForKey:#"name"];
[[ageArray objectAtIndex:0] valueForKey:#"age"];
}
-(void)viewDidUnload {
self.originalArray = nil;
self.nameArray = nil;
self.ageArray = nil;
[super viewDidUnload];
}
- (void)dealloc {
[originalArray release];
[nameArray release];
[ageArray release];
[super dealloc];
}
#end
Any ideas?
UPDATE: Thanks to #robin, by changing the code above to the code below, everything works great:
// sort by name
NSSortDescriptor *sortByNameDescriptor;
sortByNameDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"name"
ascending:NO] autorelease];
NSArray *sortByNameDescriptors = [NSArray arrayWithObject:sortByNameDescriptor];
nameArray = [[NSMutableArray alloc] initWithArray:[originalArray sortedArrayUsingDescriptors:sortByNameDescriptors]];
// sort by age
NSSortDescriptor *sortByAgeDescriptor;
sortByAgeDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"age"
ascending:NO] autorelease];
NSArray *sortAgeDescriptors = [NSArray arrayWithObject:sortByAgeDescriptor];
ageArray = [[NSMutableArray alloc] initWithArray:[originalArray sortedArrayUsingDescriptors:sortByAgeDescriptors]];
I dont think you know about this or not but when ever you create an object like string or array or dictionary, with init methods then the retain count gets incremented by 1
and if you create them like this
NSArray *anarray = [NSArray arrayWithArray:temp];
this will create an autorelease objects that will be released automatically after sometime.
So my advice don't use this type of code if you want to use the objects in more than 1 function. Always use init methods first to get the work done.
and if you are sure that the objects are not needed for the rest of the program than release them using release methode.