Adding 'data' to an NSMutable Array - Xcode - objective-c

I want to add 'email' data to my NSMutableArray so every time the button is pushed it adds another email to the array, so I end up with an array of email addresses but can't seem to get it working.
I think my problem is I am reinitialising the array so clearing it out and maybe need to put the initialisation somewhere else..which I have tried.
The below code lets me add an address but each time the IBAction is called I think I am clearing the array, any pointers or help would be great
#property (strong, nonatomic) NSMutableArray *mutable;
#synthesize mutable;
- (IBAction)array:(id)sender {
mutable = [[NSMutableArray alloc]initWithObjects:self.person.email, nil];
[mutable addObject:self.person.email];
NSLog(#"ARRAY OF EMAILS %#",mutable);
}

You are right - you are initializing the array each time the array: method is called. You can change the code to initialize it only once:
- (IBAction)array:(id)sender {
if(!self.mutable) {
self.mutable = [[NSMutableArray alloc]initWithObjects:self.person.email, nil];
}
[self.mutable addObject:self.person.email];
}
As a side note - you don't have to use #synthesize for this property. Read "Adopting Modern Objective-C" for more details.

Did you use UIViewController? If yes then reset the array in viewDidAppear method.
If you are using the UIView, then create the custom method to reset the array and call from the parent viewController.

Related

How to access content of NSMutable array from another class?

I have a FirstViewControlloller in which I have a start and stop button. When start is pressed pictures are taken by using AVCaptureSession until stop button is pressed. These pictures are processed and information (The R-value component of RGB) from each picture is stored in an NSMutableArray called Yaxis.
Added to this View I have a ContainerView. In this view I want to continously display a graph of the information in my Yaxis-array. The problem is to reach this information.
Some parts of my code follow here:
FirstViewController.h
#property (nonatomic, strong) NSMutableArray *Yaxis;
FirstViewController.m
-(void)viewDidLoad{
Yaxis=[[NSMutableArray alloc] init];
[super viewDidLoad];
}
At another place in the code objects are continuously added to "Yaxis" as pictures are taken.
[Yaxis addObject: RGB];
This works fine since I have no problem accessing the array filled with information as long as Im in FirstViewController.
To be able to use this information to update my graph I have tried to create an object of FirstViewController in my ContainerViewController and in that way reach my Yaxis array.
ContainerViewController.m
FirstViewController * myView=[[FirstViewController alloc] init];
myView.Yaxis
When I do this Yaxis is null. As I understand it the problem is that I create a new object of FirstViewController and therefore I will not be able to reach the filled array that is actually a part of another object. So how do I get connected to the object that holds my filled Yaxis array from within my ContainerViweController class?
Access NSMutableArray from another class - Objective C
I found this question that seams to adress the same problem but I did not solve my problem using the answers from there.
You initialize the array in -(void)viewDidLoad. But that method is not called anywhere in your second code snippet. Try putting the Yaxis=[[NSMutableArray alloc] init]; line in your init method
When you manually create a new FirstViewController, this is a new object unrelated to the original, and the mutable array property is initially nil.
The new VC will not magically point to the one that's displayed. Also, the VC might get destroyed, and the array released.
You should separate the storage of this data in another object if it's shared between VCs.

I can't add my data object to my NSArray

So I have this method:
-(void)addLaneToRacingLanes:(UITapGestureRecognizer*)sender{
laneDataObject *data=[self.laneDataObjects objectAtIndex:sender.view.tag];
[self.racingLanes addObject:data];
NSLog(#"%i",self.racingLanes.count);
[sender.view setBackgroundColor:[UIColor yellowColor]];
}
It uses the tag from the senders view to find out which data object corresponds to that view.I'm using this to add to my racingLanes which is how I update these views, but my problem is that for some reason I cant add my laneDataObjects to my array racingLanes. Any ideas?
This is how the properties are set up:
#property (strong,nonatomic)NSArray *laneDataObjects;
#property (strong,nonatomic) NSMutableArray *racingLanes;
I have already run through the tags and they all work. The tags work such that lane 1 is tag 0 with its data object at 0, then lane 2 is tag 1 and its data is 1, so on and so forth. I already pre-tested this. And I have checked that both the laneDataObject array has been properly set up. Is it because my racingLanes isn't using a custom getter or setter? How would I go about changing that?
Incase it matters I used
NSLog(#" %i",self.racingLanes.count);
to find out if the array was empty.
It is a near certainty that the racingLanes has not been initialized: since the objects that you are adding are non-nil (you'd see an exception thrown otherwise) the racingLanes must be nil then.
You need to set racingLanes to NSMutableArray in the designated initializer:
_racingLanes = [NSMutableArray array];
Did you make sure to initialize your NSMutableArray in your class's -init or -viewDidLoad function?
// WITH ARC
self.racingLanes = [NSMutableArray array];
// WITHOUT ARC
self.racingLanes = [[NSMutableArray alloc] init];

(Beginner)Trying to pass an array from ViewController to DetailController

I have loaded an array (recordArray) in RootViewController class which I need to pass to the DetailViewController class so that I can access any variable within it. I can pass a single value successfully, but I cannot get how to pass the whole array across.
I have created a second NSMutableArray recordArray in DetailsViewController.h, added the #property statement (with retain), and synthesized in DetailsViewController.m. I then added the following line in DetailsViewController.m
recordArray = [[NSMutableArray alloc] initWithArray:self.recordArray];
but that just gives me an empty array in the detail view.
I have read through some of the posts on this, but have not found anything which I understand sufficiently to be able to implement. I expect I'm going about this all wrong....
Thanks in advance for your help guys.
Please refer to this code:
iPhone SDK: How do I pass an array of values from a ViewController onto other ViewController?
There you can refer to Satya's answer.
Let me know if you need more help
EDIT:
Let us assume that there is an NSArray called secondArray declared in SecondViewController
Define a method in SecondViewController which says:
-(void)setValue:(NSArray *)array
{
secondArray = array;
}
Hope this helps.
The problem is that here:
recordArray = [[NSMutableArray alloc] initWithArray:self.recordArray];
You are just assigning the same property recordArray, which is probably nil at this point, what you want to do is dependency injection. So whenever you instantiate your DetailController, you can do:
myDetailController.recordArray = myRecordArray
Where myRecordArray is the value you want to pass or "inject" in the detailview controller.

NSMutableArray property getting autoreleased?

I have an NSMutableArray property defined in my Brain model.
#property (retain, nonatomic) NSMutableArray *stockColors;
The mutable array gets filled with objects during the Brain init.
In my view controller viewDidLoad function I do
*Brain brain = [[Brain alloc]init];
NSLog(#"Brain stockColors is %#", brain.stockColors);
This works well, and it logs a memory address as expected.
Then in the same view controller I have an "addButtonPressed" action declared linked to a UIButton in the .xib.
In my addbuttonPressed action if I try and do the exact same log
NSLog(#"Brain stockColors is %#", brain.stockColors);
The program crashes!
If I do
NSLog(#"Brain stockColors is %#", brain);
I get an address for the brain... so the brain exists.. but for some reason it seems that brain.stockColors is getting released or something by the time I get to the addButtonPressed action.
Can anyone explain what would cause it to get autoreleased?
Thanks
Considering you left out the important code... the actual Brain init call I am going to say that when you create your mutable array you are assigning to the instance variable and not the property.
//The Brain init method should contain something similar to this
self.stockColor = [NSMutableArray array];
//stockColor = [NSMutableArray array]; would be incorrect and get autoreleased

Table view not updating according to bindings

This is a very newbie question, and this is something I have done many times before, but there's something I'm missing this time.
In my AppDelegate.h file I declare an NSArray and set it as a property:
#interface AppDelegate : NSObject {
NSArray *lines;
}
#property(readwrite, retain) NSArray *lines;
#end
And then in the AppDelegate.m file in the awakeFromNib method I alloc it:
lines = [[NSArray alloc] init];
Then I have a method that sets the lines array:
NSString *fileContents = [NSString stringWithContentsOfFile:[NSHomeDirectory() stringByAppendingPathComponent:#"Desktop/sometextfile.txt"] encoding:NSUTF8StringEncoding error:NULL];
lines = [fileContents componentsSeparatedByString:#"\n"];
I have an array controller thats bound to AppDelegate.self.lines then I have a table column bound to Array Controller.arrangedObjects. I can confirm that the array is being updated (tested using NSLog) however the contents of the table are not being update (it remains blank).
Is there something obvious I'm missing here?
You don't need a data source if you're using Bindings. One or the other.
I have an array controller thats bound to "AppDelegate.self.lines" …
Why self?
#property(readwrite, retain) NSArray *lines;
No, use copy here. Otherwise, you'll find yourself retaining someone else's mutable array, which they will then mutate. Then “your” array will have changed without you knowing it.
Then I have a method that sets the lines array:
lines = [fileContents componentsSeparatedByString:#"\n"];
This is why the table doesn't show anything. You're not going through the property, you're accessing the instance variable directly. Direct instance variable accesses do not cause KVO notifications, so the array controller never finds out about the change.
Even worse, you're leaking the old array (since you simply assign over it without releasing it) and under-retaining this new array. Because you're not retaining the new array, that instance variable will hold a dead object shortly. The automatic retaining is done by the setLines: method, which only gets called when you call it.
You need to go through the property:
self.lines = [fileContents componentsSeparatedByString:#"\n"];
A property access is an implicit accessor message, so this both retains the array (or copies it, once you correct the #property as I suggested above) and posts KVO notifications.
When you say you have a arrangedObjects bound to the column do you mean you set the tablview datasource? If not you to set the tableview datasource to the lines array
You might want to read through this, it's got some good diagrams and explanations. What ennuikiller is saying is correct, I think it's a problem with your datasource. This is done by calling
[aTable setDelegate:aDelegate];