NSMutableArray property initialization and updating - ios

Suppose I have a #property that is an NSMutablearray that is to contain scores used by four objects. They will be initialized as zero and then updated during viewDidLoad and throughout operation of the app.
For some reason, I can't wrap my mind around what needs to be done, particularly at the declaration and initialization steps.
I believe this can be a private property.
#property (strong, nonatomic) NSMutableArray *scores;
#synthesize scores = _scores;
Then in viewDidLoad I try something like this but get an error. I just need help with syntax, I think. Or I'm missing something very basic.
self.scores = [[NSMutableArray alloc] initWithObjects:#0,#0,#0,#0,nil];
Is that an appropriate way to initialize it? Then how do I add (NSNumber *)updateValue to, say, the nth value?
Edit: I think I figured it out.
-(void)updateScoreForBase:(int)baseIndex byIncrement:(int)scoreAdjustmentAmount
{
int previousValue = [[self.scores objectAtIndex:baseIndex] intValue];
int updatedValue = previousValue + scoreAdjustmentAmount;
[_scores replaceObjectAtIndex:baseIndex withObject:[NSNumber numberWithInt:updatedValue]];
}
Is there a better way of doing this?

You are initializing in viewDidLoad, However you should do it in init.
These both are similar, and perfectly valid.
_scores = [[NSMutableArray alloc] initWithObjects:#0,#0,#0,#0,nil];
or,
self.scores=[[NSMutableArray alloc]initWithObjects:#0,#0,#0, nil];
Your last question... Then how do I add (NSNumber *)updateValue to, say, the nth value?
If you addObject: it will be added at last. You need to insertObject:atIndex: in your required index, and all following objects will shift to next indices.
NSInteger nthValue=12;
[_scores insertObject:updateValue atIndex:nthValue];
EDIT:
After your edit,
NSInteger previousValue = [[_scores objectAtIndex:baseIndex] integerValue];
NSInteger updatedValue = previousValue + scoreAdjustmentAmount;
[_scores replaceObjectAtIndex:baseIndex withObject:[NSNumber numberWithInt:updatedValue]];

Related

How to create a variable sized float type array in objective c?

I need a float type array; don't know the size of array initially. When I will get the value of size, I want to add some float values in it by a for loop. This array need to be global because I want to update it from another view controller class. How can I do this?
For this I declared a NSMutableArray type object and add float value by a for loop.
#property (nonatomic, strong) NSMutableArray *speedRate;
for (NSInteger i = 0; i < self.assetArray.count; i++){
[self.speedRate addObject:[NSNumber numberWithFloat:1.0f]];
}
NSLog(#"speedRate.count =%lu",(unsigned long)self.speedRate.count);
NSLog(#"value =%f",[[self.speedRate objectAtIndex:1]floatValue]);
But I got speedRate.count =0 and value =0.000 . I want speedRate.count will be same as self.assetArray.count and value =1.0 . How can I achieve this?
Your code never actually allocates the array. Add
self.speedRate = [[NSMutableArray alloc] init];
before the loop.

Using Text Field to add String to NSMutableArray

I am looking to get an NSString value from a Text Field and add it to an array, I want to build an array with many strings in it ex:
[hello, goodbye, too soon].
This is my current solution:
- (IBAction)submitButton:(id)sender {
NSMutableArray *wordArray = [[NSMutableArray alloc] init];
NSString *input = textField.text;
[wordArray insertObject:input atIndex:arrayIndex];
arrayIndex++;
}
This works for the first item in the array, but when I press submit again it reinitializes.My issue is how do I initialize the NSMutableArray to use in the button function, without having it in there so that it doesn't initialize every time. Thank you
Your are using a local array that disappears as soon as the submitButton method is finished.
Make your wordArray an instance variable and initialize it once in viewDidLoad. Then in your submitButton: method (and any others), you reference the instance variable instead of creating local arrays.
Honey's answer is almost, but not, correct.
Your code uses a local variable in your submitButton method, and creates a new, empty array each time the method gets called. Both of those things are wrong.
Honey's answer has you create a different local variable in viewDidLoad. That's also wrong.
You need to make wordArray an instance variable or property of your class. If you class is called ViewController, say, it might look like this
#interface ViewController: UIViewController;
#property (nonatomic, strong) NSMutableArray *wordArray
...
#end
And then initialize it in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.wordArray = [[NSMutableArray alloc] init];
}
Then in the rest of your program refer to self.wordArray, the property.
Here's the solution,
#implementation ViewController{
NSMutableArray *_wordArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
_wordArray = [[NSMutableArray alloc] init];
}
- (IBAction)submitButton:(id)sender {
NSString *input = textField.text;
[wordArray addObject:input];
}
You was re init the array each time you make the action, which will let you always save the last value of the textfield.
but this creates an array as global variable so that you can add all the values entered in textfield.
Hope this help you :)

NSMutableArray Allocate then replaceObjectAtIndex

I have a NSMutableArray that i define in the header file as:
#property (strong, nonatomic) NSMutableArray *tempPhotosArray;
Then i allocate as:
_tempPhotosArray = [[NSMutableArray alloc] init];
What i'd like to know is if i then go to replaceObjectAtIndex the program will complain on an out of bounds. I want to keep only a set number of items in that array, so is it possible to do a insert or replace? i.e. if at index 0 it is empty do an insert, if there is an object already replace it?
Thanks
i think i agree with Hani Ibrahim. Since you said you only want to keep a set number of objects in the array. So how many you want?
// add these code when you initialize the array
int aSetNumber = 5;
_tempPhotosArray = [[NSMutableArray alloc] init];
for (int i = 0; i < aSetNumber; i++)
{
[_tempPhotosArray addobject: [NSNull null]];
}
i guess then you can do whatever you want, i don't know what exactly you want to do in this case, but i would check if the object in that position is NSNUll, if so, replace that, if not, i don't know what you want them
//use these code when you trying to insert the real object
if([[_tempPhotoArray objectAtIndex:anIndex] isKindOfClass: [NSNull class]])
{
//replace it here
}
As to why you are getting an error, what everyone else wrote is accurate, but....
The description of what you want doesn't match what an NSArray is. It sounds like you want a list of up to 5 items and never more than 5. It might be that if you try to add a 6th item the "oldest" goes away. Like a "recently opened" file history. You can make this type of functionality with an NSArray, but that's not what it is out of the box.
I would suggest making your own object class. I'm not going to write all the code for you, because this sounds suspiciously like programming homework, but I will point you in the correct direction.
FivePack <-- our class
NSArray *storage; <-- where we house the data
// a public method which lets you add things.
- (void)addItem:(id)item {
int indexOfLastItemInArrayToSave = 4;
if (storage.length < 4)
indexOfLastItemInArrayToSave = length-1;
NSRange range = NSMakeRange(0, indexOfLastItemInArrayToSave);
NSArray *temp = [storage subArrayWithRange:range];
// now create a new array with the first item being "item" that
// was passed in and the rest of the array being the contents of temp.
// Then save that to storage.
}
What you want to do with the data and writing something to get it from your new object is up to you, because I'm not sure how you want to do it.
There are no objects in the array when you initially created it, so there is nothing to replace.
Like this?
if([_tempPhotosArray count] > 0)
//replace object
else
//add object to array

Why is my object is not storing the NSNumber Data and returning 0 as the value?

I have an object: indivOrder:
#interface indivOrderDetails : NSObject{
NSNumber* shirtNumber;
NSNumber* pantsNumber;
NSNumber* jacketNumber;
NSNumber* laundryNumber;
NSNumber* blouseNumber;
NSNumber* blazerNumber;
NSNumber* skirtNumber;
NSNumber* suitNumber;
NSString* pickUpOrDropOff;
NSString* pickUpFrom;
NSNumber* totalOrderPrice;
}
They're all given the interface of
#property (nonatomic, retain) NSNumber* propertyName
I have three steps.
First I retrieve the data from a text field:
shirtNumber = [self convertStringToNumber:shirtField.text];
Second, I use this convertStringToNumber method.
-(NSNumber*) convertStringToNumber:(NSString*)stringToConvert
{
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber *myNumber = [f numberFromString:stringToConvert];
return myNumber;
}
Then I assign that value to my object variable.
orderDetails.shirtNumber = shirtNumber;
But the only value I'm coming back with when I try to access the orderDetails.shirtNumber variable is zero. The shirtNumber is coming back with the correct value from the ViewController.
Your problem likely lies here:
shirtNumber = [self convertStringToNumber:shirtField.text];
Look at that to which you're assigning. It's one of the ivars you declared. That ivar, despite what you may think, is not the backing for your property of the same name. The backing instead would be
_shirtNumber
since you don't appear to have synthesized (i.e., used the #synthesize directive) any accessors.
As a result, _shirtNumber and shirtNumber are two distinct entities, which means that when you attempt to access
orderDetails.shirtNumber
of course it's going to be nil. You never put anything in it.
So you have two choices: Either use the property name that's prefixed with an underscore
_shirtNumber = [self convertStringToNumber:shirtField.text];
or use #synthesize to set up some accessors, in which case you'd do this
self.shirtNumber = [self convertStringToNumber:shirtField.text];
or this (if you like the old form)
[self setShirtNumber:[self convertStringToNumber:shirtField.text]];
Guess that's three choices. Anyway, it's a subtle, classic 'gotcha.' If you want further background for this, you can find it in this very excellent explanation elsewhere on Stack Overflow.
Good luck to you in your endeavors.

passing values string values to an object and recieving a string in return in ios

Hi a very simple app it takes in 2 arguments via 2 text boxes, and then totals them and displays them in a label called result. The idea is to have it handled via an object called brain, for which in the later part i have given the code. problem is foo is zero and when you click the button the result goes to nothing.
The plan is to use this to build a better model view architecture for a bigger app i have completed.
#import "calbrain.h"
#import "ImmyViewController.h"
#interface ImmyViewController ()
#property (nonatomic, strong) calbrain *brain;
#end
#implementation ImmyViewController
#synthesize brain;
#synthesize num1;
#synthesize num2;
#synthesize result;
-(calbrain *) setBrain
{
if (!brain) {
brain = [[calbrain alloc] init];
}
return brain;
}
- (IBAction)kickit:(UIButton *)sender {
NSString *number1 = self.num1.text;
NSString *number2 = self.num2.text;
NSString *foo;
foo = [brain calculating:number1 anddouble:number2];
self.result.text = foo;
// self.result.text = [brain calculating:self.num1.text anddouble:self.num2.text];
}
#end
#implementation calbrain
-(NSString *) calculating:(NSString *)number1 anddouble:(NSString *)number2
{
double numb1 = [number1 doubleValue];
double numb2 = [number2 doubleValue];
double newresult = (numb1 + numb2);
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSString *numberAsString = [numberFormatter stringFromNumber:[NSNumber n numberWithFloat:newresult]];
return numberAsString;}
Check your brain using NSLog in the (IBAction)kickit:(UIButton *)sender function. I guess you didn't initialise brain. If this is not the case, you need to provide more code.
i did just that, i came to the conclusion the setter for brain isnt working properly
i put the alloc init line of code before i needed to alloc init the brain, and it works fine, i stubbed out the setter,
i will go back and see why it wasnt overriding the setter made by properties, but interesting stuff none the less. it means i can change my actual larger app to have a cleaner more organised architecture.
thanks for your time.
Try initializing your brain object in viewDidLoad() using your setter method. You have to call setter method to get your brain object initialized.
Something like this
viewDidLoad()
{
brain = [self setBrain];
//You can also do this
brain = [[calbrain alloc] init];
}
and use that brain object in your (IBAction)kickit: method.
Hope this helps.

Resources