2D array in Objective C - iphone

I want to create a global array, I was looking in to NSMutableArray because you can index it. I need to be able to call specific lines of the array and display via a label the 1st part of the array and compare users input with the second part.
Example is: User sees, press "x" (this is the first part of the array) and if the click one button it will compare that button id to the second part of the array.
Im not familiar with arrays in objective C, links or code snips will help!

It sound like a bit like you have a question answer format...
What you could do is have an NSArray of Question the objects that may look something like
#interface PSQuestion : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, assign) NSInteger answer;
#end
#implementation PSQuestion
#synthesize title = _title;
#synthesize answer = _answer;
#end
Nw you can have an indexed array of objects that contain both components you require
// Configure questions
PSQuestion *question1 = [[PSQuestion alloc] init];
question1.title = #"Click X";
question1.answer = 2;

I need to be able to call specific lines of the array and display via
a label the 1st part of the array and compare users input with the
second part.
No problem! NSArray or it's mutable counterpart can store strings just as easily as any other object. It's as simple as [mymutablearray addObject:#"mystring"];.
User sees, press "x" (this is the first part of the array) and if the
click one button it will compare that button id to the second part of
the array.
To compare two arrays use [_array1 isEqualToArray:array2];, to compare strings within an array to a button label, use
[[array1 objectAtIndex:0]isEqualToString:myButton.titleLabel.text];

Looks like you only need a one dimensional array of objects that have two elements. Define a class that has the two parts of which you speak, and then make an NSMutableArray full of instances of that class.

Related

Showing something different in a label every time the view is loaded

What I want to do, is when the app is loaded, the user see's a tip. I have about twenty of them and I want just a label to show them. I can show them in order, I just don't know how to show a different one every time. So is their a method to just go through an order every time the view is loaded?
so far i have done this
Made a tip lebel to be set
#property (weak, nonatomic) IBOutlet UILabel *tipLabel;
and im gunna set it in the view did load
#synthesize tipLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
tipLabel.text = // What Do I put here to pick from my list of 20 strings?
(in order or random)
You don't say where or how you are storing your list (or array) of 20 strings, but assuming it is a "NSArray" object with 20 strings, you could do something like this:
tipLabel.text = [arrayOfTips objectAtIndex: (arc4random() % [arrayOfTips count])];

How to store NSTimeInterval values into a NSMutableArray?

I have a requirement where i have a Video that is played using MPMediaPlayerController. Along with the video i have two buttons where i need to capture the current playback time when the button are clicked and store all the relevant clicks individually. I am able to get the current playback time of the video using "currentPlaybackTime" property which returns NSTimeInterval. But can someone help me in how to store all the NSTimeInterval values into an NSMutableDictionary. I have tried the following ways:
-(void)onClickOfGood {
NSLog(#"The current playback time in good:%g",moviePlayerController.currentPlaybackTime);
currentPlaybackTime = moviePlayerController.currentPlaybackTime;
//NSArray *arrayContainsGoodClicks = [[NSArray alloc]initWithObjects:currentPlaybackTime, nil ];
NSNumber *goodTimeIntervals = [NSNumber numberWithDouble:currentPlaybackTime];
NSMutableArray *arrayContainsGoodClicks = [[NSMutableArray alloc]initWithObjects:goodTimeIntervals,nil ];
NSLog(#"The total count of Array is: %i",[arrayContainsGoodClicks count]);}
But everytime after the click of good button i am getting the Array count as only 1. Can someone please throw a light on where i am going wrong?
But everytime after the click of good button i am getting the Array count as only 1.
This is not surprising, considering that you are creating a brand-new NSMutableArray on the previous line.
To fix this, you need to make NSMutableArray *arrayContainsGoodClicks an instance variable (AKA ivar), initialize it to [NSMutableArray array] in your designated initializer, and then use
[arrayContainsGoodClicks addObject:goodTimeIntervals];
to add objects to the array.
If you are looking to use NSMutableDictionary instead, the strategy would be identical, except you would need to decide on an object that you would like to use as unique keys to your NSDictionary. Also remember that NSMutableDictionary is not ordered, so you might need to take care of sorting each time you display your dictionary items to users.
You need to create arrayContainsGoodClicks only once (in init method for example) and then add value to this array in your button handler:
//.h
NSMutableArray *arrayContainsGoodClicks;
//.m - init
arrayContainsGoodClicks = [NSMutableArray array];
//.m - button handler
[arrayContainsGoodClicks addObject:goodTimeIntervals];
You need to create your array and store it as a ivar.
#property (retain, nonatomic) NSMutableArray *clicksArray;
...
#synthesize clicksArray;
Now in your -init method create the array like..
self.clicksArray = [NSMutableArray array];
And add the object to the array each time so your -onClickOfGood would become something like...
...
[self.clicksArray addObject: goodTimeIntervals];
NSLog(#"The total count of Array is: %i",[self.clicksArray count]);

Passing data in an array from one class to another

hoping for advice on something.
I have a Levels Engine class that creates an NSMutable Array called levelsArray.
I am passing the data to a Levels View Controller which is working just fine.
I also have a Particle Emitter class to which I am hoping to pass the level data.
However I am constantly being told that the count level of the array is 0 when I pass it to the Particle Emitter class.
The array has been setup properly:
**LevelsEngine.h**
#interface
LevelsEngine : NSObject {
NSMutableArray *levelsArray; }
#property (retain) NSMutableArray
*levelsArray;
**LevelsEngine.m**
#synthesize levelsArray;
LevelsArray =[NSMutableArray array];
**Code used in ParticleEmitter.m**
newlevelsArray = [NSMutableArray array];
newlevelsArray=view.levelsArray;
Am I right in thinking I am having this error because I am trying to pass the array data from one NSObject to another and not to a view controller?If so how can I pass the data?
Couple of things.
**Code used in ParticleEmitter.m**
newlevelsArray = [NSMutableArray array];
newlevelsArray=view.levelsArray;
The first line is creating a new array.
The 2nd line is assigning newlevelsArray to be a pointer to the array in view.levelsArray, leaving the object you created in line #1 orphaned.
I think you were intending the 2nd line to be a field by field copy of the array, but assignments of objects don't work that way.
You can fix this by 2 things.
1) Remove the first line newlevelsArray = [NSMutableArray array];
2) Change the 2nd line to `newlevelsArray = [view.levelsArray copy];
This will actually do a copy, which is probably what you want since you can then go ahead and modify newlevelsArray in ParticleEmitter.m without changing the value in view.
Important note: don't forget to create a -dealloc: method in your Particle emitter class which releases newlevelsArray:
-(void)dealloc {
if (newlevelsArray) [newlevelsArray release];
[super dealloc];
}
An alternative solution is to use setters.
Instead of:
2) Change the 2nd line to newlevelsArray = [view.levelsArray copy];
Do:
2) Change the 2nd line to this.newlevelsArray = view.levelsArray;
Where you have to define newlevelsArray to be a property of the ParticleEmitter class using
#property (copy) NSMutableArray * newlevelsArray;
Note the use of "copy" instead of "retain". This will do a field by field copy of the array, which is most likely advisable for containers of mutable objects.
You need to change your code,
call the newlevelarray in the LevelsEngine.h calls.
and your code should look like
Classobject.newlevelsArray =[nsarray arraywitharray: LevlesArray] ;
This should solve your problem.

trying to add dictionary objects to an NSMutableArray - afterward array returns null?

I just did a search for my particular question and although the answers are close, I can't get my head around the answer...so I need some assistance.
I'd like to populate an array (NSMutableArray I suppose) with a group of dictionary objects that are parsed from JSON strings...the dictionary part I got, the JSON parsing I got, but when I try to put these objects into the NSMutableArray and NSLog it I get (null)... here are my steps (in a general way)
edit 1:
-The array I am creating is called NewFinalArray. it is an NSMutableArray, declared at the .h file and synthesized (and now alloc'd and init'd) as noted in the viewDidLoad method of the DetailViewController. It's contents are to be displayed in a UITableView.
-In DetailViewController, I have been successful in creating a plain NSArray/NSMutableArray and populating it with values that display in my UITableView.
-In the new scenario, I am receiving the information to be displayed through JSON strings which are retrievable through dictionary objects. I am using the Stig JSON libraries for iPHone/iPad. I have no problems there.
-All I wanted to do is getting the existing dictionary objects (which I can loop through from the existing array and see) and add them to a new Array to be used for displaying menu items in my UITableview.
I declared my mutableArray in my .h file
#interface blah : ...,...,...{
NSMutableArray *newFinalArray;
// other vars and IBOutlets
}
#property (nonatomic, retain) NSMutableArray *newFinalArray;
// other #property and (IBAction) stuff
#end
I then synthesize it in my .m file... I even alloc/inited it at viewDidLoad (it's a DetailViewController)
#synthesize this,that, newFinalArray; // keep track of newFinalArray, that's the one I want
- (void)viewDidLoad {
// other code
[[newFinalArray alloc] init]; // ya returns a warning, about not responding to alloc, but whatever (for now)
// I also tested of course without having to do that.
in my method that uses newFinalArray, the method is a recursive function that calls itself. each time it calls, it should add the dictionary object to the array (or does it?)
-(void)digTree:(NSArray *)array{
for (NSDictionary *dictionary in array){
// looping through the array
[self newFinalArray addObject:[dictionary]];
// more other code, and somewhere along the way I recurse
[self digTree:anotherArray];
}
}
when I try to NSLog (#"my final array is %#", newFinalArray) I get (null).
I am probably missing something here. I tried to add "nil" at the end. I am a little new/green to this , so if someone can lend a hand and let me know how to populate my newFinalArray with these dictionary objects it would be most appreciated.
[[newFinalArray alloc] init];
should be:
newFinalArray = [[NSMutableArray alloc] init];
This line is wrong too:
[self newFinalArray addObject:[dictionary]];
it should be:
[newFinalArray addObject:dictionary];
The first thing I notice that is wrong, is it should be:
newFinalArray = [[NSMutableArray alloc] init];
in viewDidLoad. See if that fixes it. It looks like there are other things wrong as well, so turn on warnings and see what else the compiler warns you about for hints.
How are the dictionaries stored? An alternative/probably easier way to do this would probably be to use arrayWithObjects:. Also, when using addObject:, there is no need to add nil (in fact, you can't add nil).

replaceObjectAtIndex array problems

Been searching for the answer to this for a while now and I think due to the nature of my array set up, I may be searching for the wrong answer!
I have a class which handles adding items to my array:
// Item.h
#interface Item : NSObject {
NSString *name;
NSNumber *seconds;
}
#property(nonatomic,copy) NSString *name;
#property(nonatomic,copy) NSNumber *seconds;
- (id)initWithName:(NSString *)n seconds:(NSNumber *)sec;
#end
and...
//item.m
#implementation Item
#synthesize name, seconds;
- (id)initWithName:(NSString *)n seconds:(NSNumber *)sec {
self.name = n;
self.seconds = sec;
return self;
}
#end
So to add an item, I use
Item *item1 = [[Item alloc] initWithName:#"runnerA" seconds:[NSNumber numberWithInt:780]];
I have some code which allows a user to edit a textfield (runner name) and the time which is a UIdatepicker set to hours and minutes. In the save method, that's working fine. It's the UPDATE that I cannot get to work. I've tried alsorts! Here's the code at the moment...
mainAppDelegate *appDelegate = (mainAppDelegate *)[[UIApplication sharedApplication] delegate];
Item *item = [[Item alloc] initWithName:inputName.text seconds:[NSNumber numberWithInt:secs]];
[appDelegate.arrItems replaceObjectAtIndex:rowBeingEdited withObject:item];
The above is simply adding a new item to the array (which is what I don't want). I'm not sure how to replace values. At the function, I have the row I need to update (rowBeingEdited) and the fields inputName.text and secs are both OK. (NSLog out confirms this).
How do I use the replaceObjectAtIndex to actually replace it with the values?! It's driving me mad now!!
Since you are simply trying to edit a particular row, why not use those property accessors that you already have set up in Item? It would look something like this:
Item *item = (Item *)[appDelegate.arrItems objectAtIndex:rowBeingEdited];
[item setName:inputName.text];
[item setSeconds:[NSNumber numberWithInt:secs]];
An a side note, are you using garbage collection, or do you manually release the Item objects that you create when adding items to the array? If you are doing it manually, it should look like this:
Item *item1 = [[Item alloc] initWithName:#"runnerA"
seconds:[NSNumber numberWithInt:780]];
[appDelegate.arrItems addObject:item1];
[item1 release];
This follows the rule of thumb: if you alloc, copy or retain anything, you must also release it. Note that this works because the array will retain the item when it is added.
Are you using NSArray or NSMutableArray?
Assuming you are using NSMutableArray, how did you initialize and populate the array in the first place?
For example, it's not enough to use -initWithCapacity: or +arrayWithCapacity: which only sets aside space. You have to use -addObject: for the first round of population, before you can use -replaceObjectAtIndex:withObject::
Note that NSArray objects are not like C arrays. That is, even though you specify a size when you create an array, the specified size is regarded as a “hint”; the actual size of the array is still 0. This means that you cannot insert an object at an index greater than the current count of an array. For example, if an array contains two objects, its size is 2, so you can add objects at indices 0, 1, or 2. Index 3 is illegal and out of bounds; if you try to add an object at index 3 (when the size of the array is 2), NSMutableArray raises an exception.