Why can't I just change the value in an array in xcode.

I am so annoyed at this, I can hardly type.  For 20 years I could simple change an array by doing something simple like sArray(20) = "New Array Value"

With all the technology available it baffles me that those designing languages are making it more complex.  In any event, can someone please help me set the value of a mutable array.
NOTBOB90Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Hamidreza VakilianSenior iOS/Android DeveloperCommented:
NSMutableArray* array = [NSMutableArray new];//initialization
[array addObject: someObject];//simply adding an object to the array
[array insertObject: someObject2 atIndex:0];//inserting an object at desired index
[array replaceObjectAtIndex:0 withObject: someObject3];//replacing an object this is what you are looking for

Open in new window


You should notice that you can only add NSObject derived objects to NSMutableArray.... e.g. You cannot add int or bool directly to this kind of array.
0
NOTBOB90Author Commented:
Ok so how do you change a value.
0
NOTBOB90Author Commented:
Ok so how do you change a value.
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Hamidreza VakilianSenior iOS/Android DeveloperCommented:
For example you want to change the value at index 5 to newObject:

int index = 5;
[array replaceObjectAtIndex: index withObject: newObject];
0
NOTBOB90Author Commented:
Ok I tried that and I think the problem I am having is this is a global array.  I want to set this array up in the main file, but be able to use it in multiple viewcontrollers.  

In the Main file I have:

NSMutableArray *gArrBot1;

--------------------------

Then in FrontViewController.m I have:

       

        extern NSArray *gArrBot1;
   
       
        [NSMutableArray *gArrBot1 = [NSMutableArray new];//initialization   RIGHT HERE
       
        [gArrBot1 addObject: @"ACTONE"];
        [gArrBot1: @"37"];
        [gArrBot1 addObject: @"83"];

 [gArrBot1 replaceObjectAtIndex:0 withObject: @"RANDY"];  

I get an error on the line I marked RIGHT HERE

The error is Expected Identifier
       
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
You cannot declare global variables that way. You should declare it in yourAppDelegate.h file. viewControllers can only access yourAppDelegate properties. So to make a global variable we make a property in yourAppDelegate.h:

In yourAppDelegate.h add this line before @end:
@property (retain, nonatomic) NSMutableArray* array;

Open in new window


Now in yourAppDelegate.m add this after @implementation:
@synthesize array;

Open in new window


Then at the top of your viewController header file include the yourAppDelegate header file:
#import "yourAppDelegate.h"

Open in new window


Now in the body of your viewController:
yourAppDelegate* theAppDelegate = [[UIApplication sharedApplication] delegate];
NSMutableArray* theGlobalArray = [theAppDelegate array];
//now do whatever with theGlobalArray

Open in new window


Notice: in objective c there's no global variable, instead we have properties.
0
NOTBOB90Author Commented:
Here is the code that gets triggered when I click a button.  I used the code you sent me and made some modifications as I thought needed done.  Array1Update 1-3 are labels.  When I run this it clears the default label text and makes it blank.  In other words I don't think any array is being loaded. :(  frustrating
-(IBAction)actBuildArray:(id)sender

{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
    [theGlobalArray addObject:@"ARRAY 0"];
    [theGlobalArray addObject:@"ARRAY 1"];
    [theGlobalArray addObject:@"ARRAY 2"];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
    
    
}

Open in new window

0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Beacause you have not initialized theGlobalArray. Add
theGlobalArray = [NSMutableArray new];

Open in new window

before adding the strings to it.
0
NOTBOB90Author Commented:
Well that updated my labels correctly - thanks.  The only problem is the values that are loaded there do not stay when I go to another method or a different viewcontroller.  I have to reload the array and the values are reset.
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
For initialization use:
if (!theGlobalArray)
theGlobalArray = [NSMutableArray new];

Open in new window

The issue probably was that you initialize it every time you want to access it. You should initialize it once, to retain your data.
0
NOTBOB90Author Commented:
I added the code for the 2 buttons that call actions.  The first one works fine, but the second one give me an error about array out of range.

I just want to be able to load array variables in the first action and read/change them in the second action.  I also want to do this across view controllers.
-(IBAction)actBuildArray:(id)sender

{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
     theGlobalArray = [NSMutableArray new];

    [theGlobalArray addObject:@"TEXT FOR ARRAY 0"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 1"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 2"];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
       
}

-(IBAction)actShowArray:(id)sender

{
    
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
    theGlobalArray = [NSMutableArray new];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(1)];
 
}

Open in new window

0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
In actShowArray add
If (!theGlobalArray)

Open in new window

right before
theGlobalArray = [NSMutableArray new];

Open in new window

0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
I corrected the code for you, here:


-(IBAction)actBuildArray:(id)sender

{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
   
     theGlobalArray = [NSMutableArray new];

    [theGlobalArray addObject:@"TEXT FOR ARRAY 0"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 1"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 2"];
   
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
       
}

-(IBAction)actShowArray:(id)sender

{
   
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
   
    If (!theGlobalArray)
    theGlobalArray = [NSMutableArray new];
   
    Array1Update.text = [theGlobalArray objectAtIndex:(1)];
 
}
0
NOTBOB90Author Commented:
I get an error when I copy your updated code in.

Implicit declaration of function "if" is invalid in c99

on this line:

 If (!theGlobalArray)
    theGlobalArray = [NSMutableArray new];
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Oh it is a mistype. if should be in lower case letters... change those 2 lines to:
if (!theGlobalArray)
ThGlobalArray = [NSMutableArray new];

0
NOTBOB90Author Commented:
Ok when I run that I get an error in the main file:

int main(int argc, char *argv[])
{
   
   
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([ArrayTestAppDelegate class]));
    }
}

The error in on the return line and says Thread 1 Program receives signal sigbrt
0
NOTBOB90Author Commented:
2012-01-08 10:36:00.708 ArrayTest[812:f803] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(0x13bc052 0x154dd0a 0x13a8db8 0x2d0f 0x13bdec9 0x165c2 0x1655a 0xbbb76 0xbc03f 0xbb2fe 0x3ba30 0x3bc56 0x22384 0x15aa9 0x12a6fa9 0x13901c5 0x12f5022 0x12f390a 0x12f2db4 0x12f2ccb 0x12a5879 0x12a593e 0x13a9b 0x22b8 0x2215 0x1)
terminate called throwing an exceptionCurrent language:  auto; currently objective-c
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
The error means you are requesting object with index 0 but it does not exist in the array. It's because actShowArray gets executed before actBuildArray.
actBuildArray should be called before actShowArray. Correct your code due to this...
0
NOTBOB90Author Commented:
But I am running the code in the first method first which adds three objects to the array
0
NOTBOB90Author Commented:
You see this is my whole frustration.  I am able to add and edit things in the same method, but as soon as I go somewhere else (another method) the array disappears.  I populate with one method and want to edit in another, but nothing is there.
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Change actShowArray to:

-(IBAction)actShowArray:(id)sender

{
   
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
   
    Array1Update.text = [theGlobalArray objectAtIndex:(1)];
 
}

If it does not work again, please send your complete source file of the viewcontroller.
0
NOTBOB90Author Commented:
Did not work again.  I clicked first button it load the array and updated the labels.  When I then click on second button it made the first label blank.  Sending code
#import "ArrayTestViewController.h"
#import "ArrayTestAppDelegate.h"
#import "PageTwo.h"

@implementation ArrayTestViewController

@synthesize Array1Update;
@synthesize Array2Update;
@synthesize Array3Update;
@synthesize theArray;

-(IBAction)actBuildArray:(id)sender

{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
    theGlobalArray = [NSMutableArray new];
    
    [theGlobalArray addObject:@"TEXT FOR ARRAY 0"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 1"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 2"];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
    
}

-(IBAction)actShowArray:(id)sender

{
    
//    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
 //   NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
 //   if (!theGlobalArray)
        
  //  theGlobalArray = [NSMutableArray new];
    
   // Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    
    
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(1)];
    
    
}


-(IBAction)actSwitchView:(id)sender
{
    
    PageTwo *second =[[PageTwo alloc]initWithNibName:nil bundle:nil];
    
    [self presentModalViewController:second animated:NO];    
}



-(IBAction)actChangeArray:(id)sender

{
    
    
     Array1Update.text = [theArray objectAtIndex:(2)];  
    
    [theArray replaceObjectAtIndex:(2) withObject:@"IT WORKED"];
    

    Array2Update.text = [theArray objectAtIndex:(2)];
    Array3Update.text = [theArray objectAtIndex:(5)];
   
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [self setArray1Update:nil];
    [self setArray2Update:nil];
    [self setArray3Update:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

Open in new window

0
NOTBOB90Author Commented:
I know the code for actChangeArray is wrong, that is my next step is to change the array in that method and post it to the label.  My final step is to switch to the page 2 controller and make modification there and post them back to the first controller.
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Wowww I got it. Are you programming in ARC mode (automatic reference counting) or not? Arc is only available in xcode 4.2

If you are not, I guess so, we should retain our objects... Tell me if you are not coding in ARC mode so I will repeair the code for you...
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
If you are not sure about the answer add this line after array initialization:
[theGlobalArray retain];

If you got error, then you may be in ARC...
0
NOTBOB90Author Commented:
It is version 4.2.1
0
NOTBOB90Author Commented:
It puts and error and says ARC FORBIDS EXPLICIT MESSAGE SEND of 'RETAIN'
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
So here is your new actBuildArray:

-(IBAction)actBuildArray:(id)sender
{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
   
    theGlobalArray = [NSMutableArray new];
    [theGlobalArray retain];

   
    [theGlobalArray addObject:@"TEXT FOR ARRAY 0"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 1"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 2"];
   
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Ignore my last comment. Can you provide the header and source of appdelegate class?
0
NOTBOB90Author Commented:

#import <UIKit/UIKit.h>

@class ArrayTestViewController;

@interface ArrayTestAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ArrayTestViewController *viewController;



@property (retain, nonatomic) NSMutableArray *theRGArray;

@end

Open in new window

0
NOTBOB90Author Commented:

//
//  ArrayTestAppDelegate.m
//  ArrayTest
//
//  Created by Randy Gardner on 1/6/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "ArrayTestAppDelegate.h"

#import "ArrayTestViewController.h"

@implementation ArrayTestAppDelegate

@synthesize theRGArray;

@synthesize window = _window;
@synthesize viewController = _viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ArrayTestViewController alloc] initWithNibName:@"ArrayTestViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

@end

Open in new window

0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
Change the load function to this:
It will run correctly now...


-(IBAction)actBuildArray:(id)sender
{
    ArrayTestAppDelegate *theAppDelegate = [[UIApplication sharedApplication] delegate];

    theAppDelegate.theRGArray = [NSMutableArray new];
    NSMutableArray *theGlobalArray = [theAppDelegate theRGArray];
    
    [theGlobalArray addObject:@"TEXT FOR ARRAY 0"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 1"];
    [theGlobalArray addObject:@"TEXT FOR ARRAY 2"];
    
    Array1Update.text = [theGlobalArray objectAtIndex:(0)];
    Array2Update.text = [theGlobalArray objectAtIndex:(1)];
    Array3Update.text = [theGlobalArray objectAtIndex:(2)];
    
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
NOTBOB90Author Commented:
WHEW WHOOOOOOOOOOOOOOOO!
0
NOTBOB90Author Commented:
THANK YOU SO MUCH !  I put that code in and it worked perfect!.  I added it to the other controller and it updates the array perfect.  Thank you so much for your time and work.  
0
NOTBOB90Author Commented:
Thanks so much again for the help.
0
Hamidreza VakilianSenior iOS/Android DeveloperCommented:
You're welcome :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Apple OS

From novice to tech pro — start learning today.