Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

medasmx

macrumors member
Original poster
Nov 9, 2008
89
0
interface file…

Code:
    IBOutlet UILabel*label;
    NSMutableArray*myArray;
    IBOutlet UITextField*someText;
}
-(IBAction)programLabel:(id)sender;
-(IBAction)addText:(id)sender;

implementation file...

Code:
- (id)init {
	if (self == [super init]) {
		myArray = [[NSMutableArray alloc] initWithObjects: nil];
        myArray = [NSMutableArray arrayWithCapacity:50];
	}
	return self;
}

-(IBAction)programLabel:(id)sender{

    label.text=[NSString stringWithFormat:@"%@",[myArray objectAtIndex:0]];
}

-(IBAction)addText:(id)sender{
    
    [myArray insertObject:[NSString stringWithFormat:@"%@", someText.text] atIndex:[myArray count]];    

    NSLog(@"%@",[myArray objectAtIndex:0]);
}

Logging the contents of the mutableArray, myArray, it is null. If you initialize the mutable array within the action "addText" the array is not null, but then it cannot be used in the action "programLabel". As a second exercise, I tried to create a second mutable array locally (within addText), then adding its contents to myArray, using arrayWithArray, etc, but that hasn't worked either. I have google'ed extensively, and have been surprised not to find a sample addressing this online or in books, because it seems like it would be used commonly. In any case, any help is appreciated.
 

admanimal

macrumors 68040
Apr 22, 2005
3,531
2
The problem is the way in which you are creating the array, and the fact that you probably need to read up on memory management in Objective-C.

One of these two lines in your init is redundant:

Code:
myArray = [[NSMutableArray alloc] initWithObjects: nil];
myArray = [NSMutableArray arrayWithCapacity:50];

because both of them return a new array. You can use either one, but there is an essential difference between them when it comes to memory management that you must understand.

The first line gives you an array that your class now owns with a retain count of 1. That means this array will be valid as long as your class is, assuming that you release it in your class' dealloc method and not somewhere earlier.

The second line gives you an autoreleased array that you must retain if you want it to exist as long as your class does. Since you do not do this currently, myArray gets deallocated some time after init returns and before you have a chance to do anything else with the array.

If terms like retain, release, and autorelease aren't familiar to you, you should read the memory management in Objective-C guide in Apple's docs and/or other web tutorials on the subject.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Code:
- (id)init {
	if (self [COLOR=red]==[/COLOR] [super init]) {
		myArray = [[NSMutableArray alloc] initWithObjects: nil];
        myArray = [NSMutableArray arrayWithCapacity:50];
	}
	return self;
}

In addition to the reply above, there's a coding error hightlighted in red above. It should be =, not ==.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Good catch!

Skills developed while tutoring (being a TA) to 1st year students, and from coding MARC library catalogue records. :)


Since Xcode 4.x it gives warnings when you do that, and suggests to do == instead of =.
Just saying what I have noticed ;p

The idiom should be either:
Code:
self = [super init];
if (self) {
  // ...
}
return self;
or (notice the double parentheses):
Code:
if ((self = [super init])) {
  // ...
}
return self;
 

jnoxx

macrumors 65816
Dec 29, 2010
1,343
0
Aartselaar // Antwerp // Belgium
The idiom should be either:
Code:
self = [super init];
if (self) {
  // ...
}
return self;
or (notice the double parentheses):
Code:
if ((self = [super init])) {
  // ...
}
return self;


Myself, I use the first one, Have used the second too.
Can't recall when Xcode is trying to replace the = with ==, i'll try to figure it out agian and let you know x)
 

admanimal

macrumors 68040
Apr 22, 2005
3,531
2
Myself, I use the first one, Have used the second too.
Can't recall when Xcode is trying to replace the = with ==, i'll try to figure it out agian and let you know x)

Well, Xcode knows that most of the time, == is in fact the appropriate operator to use in the conditional part of an if statement rather than =. It will give you that warning if you use = without putting the whole assignment in ().
 

medasmx

macrumors member
Original poster
Nov 9, 2008
89
0
update

interface…I don't use NSMutableArray as a property

Code:
    NSMutableArray*myArray;

implementation…

Code:
- (id)init {
	self=[super init];
	myArray=[[NSMutableArray alloc]init];
	return self;
}

-(IBAction)programLabel:(id)sender{
	NSLog(@"%@",[myArray objectAtIndex:0]);
	label.text=[NSString stringWithFormat:@"%@",[myArray objectAtIndex:0]];
}

-(IBAction)addText:(id)sender{
    
    	NSString*someString=[NSString stringWithFormat:@"%@",someText.text];
	
	myArray=[[NSMutableArray alloc]initWithObjects:someString,nil];
	
	NSLog(@"%@",someString);
	NSLog(@"%@",[myArray objectAtIndex:0]);	
}

What I was looking for was the following. Declare a mutableArray in the interface, then input from the text file and add to that array in the implementation. Finally, display different elements from the array as labels. The downfall with the above is that I would like to be adding to the array (myArray) each time. What I have is creating an array with one element. Will keep working…

Appreciate comments from late last night and earlier today. Thanks.

later post--

This also works…

Code:
-(IBAction)addText:(id)sender{
    
    	NSString*someString=[NSString stringWithFormat:@"%@",someText.text];
	NSMutableArray*someArray=[[[NSMutableArray alloc]init]autorelease];
	someArray=[NSMutableArray arrayWithArray:myArray];
	[someArray addObject:someString];
	NSLog(@"%@",[someArray objectAtIndex:0]);
}

I then want to make myArray empty, and set it equal to a copy of someArray. When I tried that it didn't work. Thanks again for any advice.
 
Last edited:

admanimal

macrumors 68040
Apr 22, 2005
3,531
2
You are still creating waaay too many arrays. You should only need to initialize the array in your class' init method. Your second version of addText also still has the same problem as your original init method where you are redundantly creating the array twice in a row, and not doing appropriate memory management with either.

I would suggest stepping back and reading some more basic Objective-C tutorials and/or examples.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Code:
- (id)init {
    self=[super init];
    myArray=[[NSMutableArray alloc]init];
    return self;
}

It's a bad habit not to check self before attempting to initialize instance variables. I won't get into to it, just use one of the two idioms I posted above.

Code:
label.text=[NSString stringWithFormat:@"%@",[myArray objectAtIndex:0]];
(and)
Code:
NSString*someString=[NSString stringWithFormat:@"%@",someText.text];

Are you using this technique as an explicit defensive programming technique? Or do you not understand what this codes does?

Code:
-(IBAction)addText:(id)sender{
    
    	NSString*someString=[NSString stringWithFormat:@"%@",someText.text];
	NSMutableArray*someArray=[[[NSMutableArray alloc]init]autorelease];
	someArray=[NSMutableArray arrayWithArray:myArray];
	[someArray addObject:someString];
	NSLog(@"%@",[someArray objectAtIndex:0]);
}

This is incredibly inefficient. You start by creating a new string by copying an existing string (may be valid, but I doubt you've done it deliberately). Then you create an empty mutable array, which you promptly discard in the next line. Then you copy an existing mutable array, add an object to it, and then forget it.

All you needed was:
Code:
-(IBAction)addText:(id)sender{
    [myArray addObject:someText.text];
}

It really seems you have little understanding of what you're actually doing. I would strongly advise going back to basics and (re-)learning fundamental programming generally, and object-oriented programming more specifically.

Are you reading (or have you read) any books on Objective-C? If not, what resources are you using (or have you used)?
 

admanimal

macrumors 68040
Apr 22, 2005
3,531
2
As an additional tip, please please please put a space between a variable's type and its name when you are declaring it.

Seeing

Code:
UILabel*label;

will make most programmers want to scream.

Either of these two is acceptable

Code:
UILabel *label;
UILabel* label;

although the first is usually preferred because if you are declaring several pointer (i.e. *) variables in one statement, it -must- be done like this:

Code:
UILabel *label1, *label2, *label3;

where there is one * for each variable.
 

Icy1007

macrumors 65816
Feb 26, 2011
1,075
74
Cleveland, OH
As an additional tip, please please please put a space between a variable's type and its name when you are declaring it.

Seeing

Code:
UILabel*label;

will make most programmers want to scream.

Either of these two is acceptable

Code:
UILabel *label;
UILabel* label;

although the first is usually preferred because if you are declaring several pointer (i.e. *) variables in one statement, it -must- be done like this:

Code:
UILabel *label1, *label2, *label3;

where there is one * for each variable.

THANK YOU! Glad someone said something.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.