Passing an NSMutableArray to a DetailView from UITableViewController - iPhone - iphone

I have a UITableViewController which presents another UITableViewController when a cell is tapped. I have an NSMutableArray which I want to pass into the new UITableViewController when instantiated.
I would usually do something like :
- (void)loadStationList {
StationListView * listView = [[StationListView alloc] initWithNibName:#"StationListView" bundle:nil];
listView.dataList = newParser.stationData;
// ...
// Pass the selected object to the new view controller.
NSLog(#"New Parser is %d", [newParser.stationData count]); //This is fine - all objects in array here.
[self.navigationController pushViewController:listView animated:NO];
}
The odd thing is that dataList (the NSMutableArray pointer in the new class) is empty (I am in checking in the number of rows delegate method).
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSLog(#"Data List is %d", [dataList count]);
return [dataList count];
}
I have tried several different approaches (such as instantiating a new NSMutable array in the parent class) however nothing seems to work. This may be ARC related as I am still relatively new to ARC. Can anyone help ?

How did you declare dataList,newParser.stationData ?
Should be sth like this
#property (nonatomic, strong) NSMutableArray *dataList;
Anyway, to ensure that you do not loose any values, you may want to copy/assign each element from newParser.stationData to dataList.
Like here:
NSMutableArray * dataList = [[NSMutableArray alloc] init];
for (id arrayElement in newParser.stationData) {
[dataList addObject:arrayElement];
}
Try this instead of the simple assignment listView.dataList = newParser.stationData;. ps don't worry about efficieny this is so fast it will not matter.

Well I got round this by created an instance variable in the app delegate and then saving and reading the array from there. This does look like a bug in arc - it works with other variable types.

Related

How to copy NSMutableArray value into another NSMutableArray in iPhone?

Here, i have a NSMutableArray in my AppDelegate page, the array will be updated when the user add the values (user name) in the database. Now i want the array values(user name) to be displayed in the next view to be list out in the Picker View. I know there is more related questions is there, but i can't find the solution. Any help appreciated.
Here is my code:
The array i have declared in the AppDelegate page, named jobarray, now i need to copy the items in the jobarray into next view, there i have declared pickerarray.
pickerarray = [[NSMutableArray alloc] initWithArray:appDelegate.jobarray copyItems:YES];
But it returns error message,
['NSInvalidArgumentException', reason: '-[Coffee copyWithZone:]: unrecognized selector sent to instance 0x822d410'] where 'Coffee' is my sqlite3 object file.
Your SQLite object does not conform to the NSCopying protocol - you haven't implemented the
- (id)copyWithZone:(NSZone *)zone;
method. You can either implement this method to make your object copyable, but if you only need the copying for displaying, you'd better copy the array itself only:
NSMutableArray *newArray = [originalArray mutableCopy];
this only retains the first array's objects, no need to mess with implementing the copying protocol.
[arr1 initWithObjects:#"1",#"2", nil];
makes no sense, what you probably want is to use the NSMutableArray:
NSArray *arr1 = [NSArray arrayWithObjects:#"1",#"2", nil];
NSMutableArray *arr2 = [arr1 mutableCopy];
NSLog(#"arr1: %p, %#", arr1, arr1);
NSLog(#"arr2: %p, %#", arr2, arr2);
NSLog output:
arr1: 0x7924c50, (
1,
2
)
arr2: 0x7924f00, (
1,
2
)
To populate a UIPickerView from an array you need to first create a connection for the UIPickeView Data Source and Delegate back to the ViewController. You can do this by CTRL dragging in Interface Builder in the normal way - from your UIPickerView control.
You will also need to ensure that you include the delegate protocal to your interface file. So something like this;
#ViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate> {
}
Then you will need to create the delegated methods for the population of the UIPickerView in your implementation file.
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
//One column
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
//set number of rows
return myArrayObject.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
//set item per row
return [myArrayObject objectAtIndex:row];
}
This assumes that myArrayObject has been properly declared and populated elsewhere. I.e. in viewDidLoad - if content is static.

Accessing array from a different view controller issue

I'm trying to access an array from a custom UITableViewCell subclass. The array is created in my tableViewController. This is driving me crazy. I access other view controller's objects all the time with ViewController *vcInstance. I actually need to edit the array from my cell subclass, but I can't even NSLog it from my cell view controller. The array logs perfectly in my tableViewController. All I get is null from the cell subclass.
CustomCell.h
#property (retain, nonatomic) SongsViewController *vc;
CustomCell.m
#synthesize vc;
-(IBAction)setStateOfObjects
{
NSMutableArray *array = [[NSMutableArray alloc] initWithArray:vc.parseTrackArray];
NSLog(#"%#", array);
}
I've also simply tried: CustomCell.m
-(IBAction)setStateOfObjects
{
SongsViewController *vc;
NSLog(#"%#", vc.parseTrackArray);
}
EDIT: You're not quite understanding how object referencing works. When you request an object from an array, or some other object that is "retaining" it, you are not creating a new object. So, you don't end up with your "previous object" and an "updated object". Consider this:
NSMutableDictionary *dict = [array objectAtIndex:index];
[dict setObject:#"Hello" forKey:#"Status"];
//You don't need to add *dict back to the array in place of the "old" one
//because you have been only modifying one object in the first place
[array replaceObjectAtIndex:index withObject:dict]; //this doesn't do anything
Considering that...
The way you're going about this is backwards. Make a property in your UITableVieCell subclass for your array
interface CustomCell : UITableViewCell
#property (nonatomic,retain) NSMutableArray *vcArray;
#end
#import CustomCell.h
#implementation CustomCell
#synthesize vcArray;
-(IBAction)setStateOfObjects {
NSMutableDictionary *dictionary = [parseTrackArrayToBeModified objectAtIndex:currentIndex];
[dictionary setObject:[NSNumber numberWithBool:YES] forKey:#"sliderEnabled"];
//THIS LINE IS REDUNDANT
//[parseTrackArrayToBeModified replaceObjectAtIndex:currentIndex withObject:dictionary];
//END REDUNDANT LINE
}
//in your ViewController's delegate method to create the cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//assume previous code has CustomCell created and stored in variable
CustomCell *cell;
cell.vcArray = self.parseTrackArray;
return cell;
}
Retaining your SongsViewController seems like a bad idea. If you are using iOS 5, that should probably be weak, if before iOS 5, assign. You're likely creating a retain cycle (memory leak) with that.
When you create the CustomCell (probably in tableView:cellForRowAtIndexPath:) in SongsViewController, are you setting it's vc property?
[yourCell setVc:self];

NSArray Set property not working

Basically what i am trying to do is make a network refresh and fetch objects, store it in a nsmutable array in my app delegate. Then i have a listviewController which uses that mutable array to display data.
Setting nsarray is not working here is the code:
//Appdelegate code called after pulldown to refresh is done on listview:
[ListView setArrayElements:(NSMutableArray*)sortedArray ];
NSLog(#"sortedArray count:%d",sortedArray);
NSLog(#"ListView Array count:%d",[ListView.ArrayElements count]);
Result i get in log : "sortedArray count:12" (which is perfect)&"ListView Array count:0" (this is not the right result)
It's hard to assume without seeing more of your code but how do you define the ArrayElements property? It may not be retaining itself and you may not have initialized it when the ListView object is created.
Let me know if this works;
Make sure ArrayElements is created in your ListView.h like the following:
#property (nonatomic, retain) NSMutableArray *ArrayElements;
Or on -init or -viewDidLoad of your ListView,
self.ArrayElements = [[NSMutableArray alloc] init];
Don't forget to release what you retained:
- (void)dealloc
{
//.....
[ArrayElements release];
[super dealloc];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.mTableView reloadData];
}
use this method
Do not make the UITableView object as a property. Just use tableView object , remove 'self.' portion.
Tell me if it helps!

Sharing NSMutableArray

Hey everbody, im trying to share a NSMutableArray to another xib. The cartList.codigo is a NSMutableArray from a shared class, according to James Brannan's tutorial (http://www.vimeo.com/12164589).
When i count it, it gives me 1. But when i load the another view, gives me 0.
Whats wrong?
View that adds:
self.produtoCodigo = [[NSMutableArray alloc]init];
[self.produtoCodigo addObject:#"aa"];
CartViewController *carrinho = [[CartViewController alloc] initWithNibName:#"CartViewController" bundle:[NSBundle mainBundle]];
CartList *lista = [[CartList alloc] init];
carrinho.cartList = lista;
carrinho.cartList.codigo = self.produtoCodigo;
NSLog(#"QTD %i", [carrinho.cartList.codigo count]);
View that wants to load the item added:
- (void) viewDidAppear:(BOOL)animated {
self.produtoCodigo = self.cartList.codigo;
NSLog(#"%i", [self.produtoCodigo count]);
[super viewDidLoad];
}
Im loading the CartList class in both.
Thanks!
My guess is that you are not retaining the array, but only assigning it.
Do you retain the array in the view, something like this -
#property (nonatomic, retain) NSMutableArray * produtoCodigo;
the "retain" gives your view controller an ownership on the array and you can use it.
Since I don't have your code that is the best I can do to help.
shani
UPDATE -
Ok. you do retain it but now i see that the "produtoCodigo" array is retained but you dont pass the array in the view controller.
is seems that you can do 2 things:
in your view controller pass the viewController "produtoCodigo" to the view "produtoCodigo".
carrinho.produtoCodigo= self.produtoCodigo;
if you already pass the array to the "cartList" then remove the view "produtoCodigo" array, geter and seter (#synthesize & #property). and in the view did load you can:
produtoCodigo =[NSMutableArray arraryWithArray: self.cartList.codigo];
or if you need to use it later you can :
produtoCodigo =[NSMutableArray alloc]initWithArray: self.cartList.codigo];
and don't forget to release it later in the second option.
Hope this time it will help
shani

iPhone add to NSMutableArray from another viewController

I have a bit of a dilemma and I was wondering if the good folk here could lend me their programming expertise. I'll try to be as simple and precise as I possibly can so here goes:
I'm a new IOS developer and have only been learning for a couple of months. I am developing an iPhone application for my dissertation at university. The app is simply a guide for people who wish to develop for the iPhone themselves, consisting of tutorials. It consists of numerous Table Views but there is one thing that has got me stumped.
What im trying to do:
One feature im trying to include in my app is a bookmarks facility, this will be accessible from a tab bar. I want to be able to click on a button from any nib file (tutorial) which adds a string to an existing NSMutableArray. This string will correspond with the name of the tutorial where the IB-Action was performed and after added to the Array I can load the nib file when selecting the row at index path.
The Problem:
I can add any object to the array from within the implementation file that contains the array but cannot figure out how to add it from a different implementation file. The UITable view populates from the array perfectly but adding a new entry is another story.
I'll show you my code but i'll leave out anything that is unrelated.
BookmarksViewController.h
#interface BookmarksViewController : UITableViewController {
NSMutableArray *bookmarksArray;
}
#property (nonatomic, retain) NSMutableArray *bookmarksArray;
#end
BookmarksViewController.m
-(void)viewDidLoad {
bookmarksArray = [[NSMutableArray alloc] init];
NSLog(#"String Added");
[bookmarksArray addObject:#"String"];
[super viewDidLoad];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cell...
cell.textLabel.text = [bookmarksArray objectAtIndex:indexPath.row];
return cell;
}
-(void)dealloc {
[bookmarksArray release];
[super dealloc];
}
NOW FOR THE SECOND VIEW CONTROLLER
Ch01GettingStarted.h
#interface Ch01GettingStarted : UIViewController {
IBOutlet UIScrollView *ScrollView;
}
-(IBAction) pushChap01Bookmark:(id)sender;
#end
Ch01GettingStarted.m
-(IBAction) pushChap01Bookmark:(id)sender{
BookmarksViewController *bookmarksViewController = [[BookmarksViewController alloc]init];
[bookmarksViewController.bookmarksArray addObject:#"NewString"];
NSLog(#"ADD ENTRY");
[bookmarksViewController.tableView reloadData];
NSLog(#"RELOAD TABLE");
[bookmarksViewController release];
NSLog(#"ADD BOOKMARK RELEASE");
}
BTW - the IB-Action was declared in the header file.
Ah, i originally tried doing this as '[BookmarksViewController.bookmarksArray addObject:#"NewString"];' but I came up with an "expected ':' at '.'" error and I read somewhere that I needed to use an instance variable of BookmarksViewController so i declared it just above the addObject method.
Please be gentle with me as I haven't been doing this for long but this is certainly something that's going to be a big part of my professional future.
Any insight anyone could offer to me would be magical.
Thank you, thank you, thank you.
The problem lies in this method:
-(IBAction) pushChap01Bookmark:(id)sender
You are creating a NEW bookmarksViewController here, by doing this:
BookmarksViewController *bookmarksViewController = [[BookmarksViewController alloc]init];
You don't want to do that because you want to update the current view controller. You need to create a link from Ch01GettingStarted.
Assuming you are using Interface Builder, you could create this link using an IBOutlet. In the Ch01GettingStarted interface, add the following line:
IBOutlet BookmarksViewController *bookmarksViewController;
(Between the brackets)
I think you already know how to link this in Interface Builder.
Then just remove this line:
BookmarksViewController *bookmarksViewController = [[BookmarksViewController alloc]init];
And this line:
[bookmarksViewController release];
And it should work.
Why? The 'bookmarksViewController' variable now references the original object (the one you created in Interface Builder) that is actually displayed.
Just to be sure.
Do you have this method in BookmarksViewController.m?
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
[bookmarksArray count];
}
Because after bookmarksViewController is created. ViewDidLoad method not run yet. bookmarksArray has not been created. So bookmarksArray = nil. You can't add object to nil object. In Second Viewcontroller, You should create bookmarksViewController in loadView method. And addobject in pushChap01Bookmark.
I'm not good English. I hope you can understand it. :D