NSArray Set property not working - iphone

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!

Related

Passing an NSMutableArray to a DetailView from UITableViewController - 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.

universal array in objective C

I am making my first app, and already made it on android, and am now trying to make it on iphone, but have no objective c experience. The app is super simple except for one part, the array.
The app has a button, that when pressed, needs to store info into an array. The problem I am running into is that when I create the array in the method where the button-click actions take place, every time I click the button it creates a new array, defeating the point of the array. When I make the array outside of the method, it either doesn't pass into the method (error says undefined) or, when I declare the object in the .h file, the program compiles, but when I hit the button it crashes.
Any help would be greatly appreciated. Examples would be great, but even if someone could point me in the right direction of things to look up, that would save me from going bald.
Try something like this (this isn't ARC) -
#interface MyViewController : UIViewController {
NSMutableArray *myArray;
}
#implementation MyViewController
-(id)init {
self = [super init];
if (self) {
myArray = [[NSMutableArray alloc] init];
}
return self;
}
-(void)dealloc {
[myArray release];
[super dealloc];
}
-(IBAction)buttonPressed {
[myArray addObject:someObject];
}
#end
You need to declare your array as an instance variable (AKA "ivar") inside the curly braces section of the the interface declaration in your .h file, and also initialize it in your designated initializer.
In the .h file:
#interface MyClass : NSObject {
NSMutableArray *myArray
}
// methods
#end
In the .m file:
-(id)init {
self = [super init];
if (self) {
myArray = [NSMutableArray array];
}
return self;
}
Now you can use myArray in all instance methods of your class.
EDIT: This sample assumes that you are using automated reference counting. Since this is your first app, using ARC is a good idea (XCode asks you if you would like to use it when you create a new project).

iPhone Xcode Array List Accessible

Currently developing my first Native iPhone application, the application is going to be integrating within an existing .net application and will be using webServices. However the problem i am facing i believe is nothing more than my understanding of xcode.
I hope i can explain this...
OK within my first view, within the viewDidLoad i go off to the webservice and return my list of items (these populate the tableview) this works completely fine:
--- snippet ---
- (void)viewDidLoad {
//GET ALL ITEMS
myArray = [[NSMutableArray alloc] init];
MyWebService *webService = [[MyWebService alloc] init];
myArray = [webService getAllNewsFunction];
[super viewDidLoad];
}
--- snippet ---
Ok so i now have my tableview populated and awaiting for you to select your item (in this case a news article) i need to determine the selectedItem in order to populate the next view with the details of the article. However it appears that within the didSelectRowAtIndexPath method my array list is no longer accessible. I am very confused at this point due to if i simply create a list of items within my viewDidLoad within the current view without using my webservice for example:
--- snippet ---
// listOfItems = [[NSMutableArray alloc] init];
// [myArray addObject:#"Iceland"];
// [listOfItems addObject:#"Greenland"];
// [listOfItems addObject:#"Switzerland"];
// [listOfItems addObject:#"Norway"];
// [listOfItems addObject:#"New Zealand"];
// [listOfItems addObject:#"Greece"];
// [listOfItems addObject:#"Italy"];
// [listOfItems addObject:#"Ireland"];
--- snippet ---
the above is accessible within didSelectRowAtIndexPath and i can populate the detailview.
Can you please help me pinpoint the problem i am facing and how this can be solved. I understand i have given you the very basics so if i need to provide more information i am happy to do so.
-- update --
ok based on your response i have update the following.
I have now declared myArray as a property
#property (nonatomic, retain) NSMutableArray *myArray;
and also updated the line to:
self.myArray = [webService getAllNewsFunction];
-- update --
however i now receive an error "program received signal: "SIGABRT"" on the self.myArray line.
any ideas?
Thanks Again
If you are following naming conventions then the method [webService getAllNewsFunction] will return an autoreleased array. Therefore when you come to access it again it will most likely have been released already.
If you have used a #property to declare myArray (which you should to save yourself from these problems) then you can resolve this by doing:
self.myArray = [webService getAllNewsFunction];
This line:
myArray = [[NSMutableArray alloc] init];
is also superflous and causing a memory leak as you are reassigning the value of myArray to [webService getAllNewsFunction] immediately after without releasing the new NSMutableArray you alloc/init'd
UPDATE
So from reading your update I think you need to firstly look at the warnings your project now has which will probably read something like:
Property 'myArray' requires method 'setMyArray' to be defined - use #synthesize, #dynamic or provide a method implementation in ...
The next clue to the problem appears in the console I get something like this
-[TestAppDelegate setMyArray:]: unrecognized selector sent to instance ...
So what it all boils down to is you either need to provide the methods
- (NSMutableArray *)myArray;
- (void)setMyArray:(NSMutableArray *)myArray;
or let the compiler do it for you by adding a #synthesize statement like this
.m
#implementation YourClass
#synthesize myArray;
// The rest of your class methods
- (void)dealloc
{
// release other ivars
[myArray release];
[super dealloc];
}
The synthesize is the easier, quicker options and the compiler will arrange for the coorect memory management depending on which options you use in your #property declaration.

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: Using a NSMutableArry in the AppDelegate as a Global Variable

What i'm trying to accomplish is to have an NSMutableArray defined in the AppDelegate. I then have two UIViewControllers. One view is responsible for displaying the array from the AppDelegate. The other view is used to add items to the array. So the array starts out to be empty. View1 doesn't display anything because the array is empty. The User goes to View2 and adds an item to the array in AppDelegate. Then when the user goes back to View1 it now displays one item.
Here is how I'm trying to accomplish this
#interface CalcAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
NSMutableArray *globalClasses;
}
#property (nonatomic,retain) NSMutableArray *globalClasses;
My other view
In the viewDidload I set the array in my View to be the one in the AppDelegate. In an effort to retain values.
allCourses = [[NSMutableArray alloc]init];
CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
allCourses = appDelegate.globalClasses;
Then I would update my allCourses array by adding a new item. Then try to set the array in the AppDelegate to be equal to the modified one.
CalcAppDelegate *appDel = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"Size before reset %d",[appDel.globalClasses count]);
appDel.globalClasses = allCourses;
NSLog(#"Size after reset %d",[appDel.globalClasses count]);
What I'm seeing that's returned is 2 in the before, and 2 after. So it doesn't appear to be getting updated properly. Any suggestions?
A few things:
First, in your app delegate you need to make sure that you intialize the array before any object tries to access it. A customer getter is good for this.
-(void) getGlobalClasses{
if (globalClasses!=nil) {
return globalClasses;
}
NSMutableArray *newArray=[[NSMutableArray alloc] initWithCapacity:1]; //yes, I'm old school
self.globalClasses=newArray;
[newArray release];
return globalClasses;
}
Now any call to the property is guaranteed to return an array.
In your view controllers, you need to define properties to hold the array. Since the array is held by the app delegate and will always be there, it is best to assign the array instead of retaining it. That way you always know you are writing to the exact same array and the app delegate has complete control over its life cycle.
In the view controllers:
#property(nonatomic,assign) NSMutableArray *globalClasses;
then every time you reference it make sure to use the self notation:
self.globalClasses=//...whatever
Having said all this, it is extremely bad practice to stick an array or any other dumb data object out their buck naked in your app. You have no control over what each piece of code will do to the array. You will have to duplicate all your validation code every place you add or remove data to the array.
It would be better to wrap the array in a custom class and make it protected so it can only be altered by the classes methods.
Like so:
#interface MyData : NSObject {
#protected
NSMutableArray *myDataArray;
}
-(void) addObject:(id) anObject;
-(void) removeObjectAtIndex;(NSInteger) anIndex;
#end
scratch.m
#interface scratch ()
#property(nonatomic, retain) NSMutableArray *myDataArray;
#end
#implementation scratch
#synthesize myDataArray;
-(void) addObject:(id) anObject{
//...code to check if anObject is a valid one to add to the array
[self.myDataArray addObject:anObject];
}//------------------------------------addObject:------------------------------------
-(void) removeObjectAtIndex;(NSInteger) anIndex{
//... do bounds checking and other testing to ensure no problems
// will result from removing the object at the given idex
[self.myDataArray removeObjectAtIndex:anIndex];
}//-------------------------------------(void) removeObjectAtIndex;(NSInteger) anIndex------------------------------------
Then add the custom class an a property of the app delegate as shown above. This will keep your data clean and modular so you can safely use it in a wide range of app reobjects without having to micromanage the array in every object.
There are a couple problems here:
allCourses = [[NSMutableArray alloc] init];
CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
allCourses = appDelegate.globalClasses;
You do not need to allocate a new array since you want to retain an existing array (the one in the app delegate)
If you're using properties, you need to use the self declaration to retain the app delegate array
Instead, try:
CalcAppDelegate *appDelegate = (CalcAppDelegate *)[[UIApplication sharedApplication] delegate];
self.allCourses = appDelegate.globalClasses;