objective-c how to synchronize two objects between rootViewController and modalViewController - iphone

I'm new to OOP and I'm confused about this following line on chapter 6 of head first iphone development:
addDrinkVC.drinkArray = self.drinks
the purpose is to assign the self.drinks NSMutableArray to another NSMutableArray in modal viewController addDrinkVC.
But why when you added an object into drinkArray in modal view and returned to the rootView and reload the tableView, self.drinks also gets changed? Is it related to the concept of pointer?
Thanks!

Unless drinkArray is declared with #property (copy), the contents of the array are not copied. This does indeed have to do with pointers. Since the array is mutable, and since you are not copying it – only adding a new reference to it – any changes made to either reference will be visible on the other. In other words, there is only one actual array in use.

Related

How to make a delegate object accessible throughout a ViewController

I'm trying to get an instance of my AppDelegate accessible to all methods in each ViewController that I have. If I try to declare it with other class variables I get Initializer Element is not a compile-time constant. If I declare it in a method within the ViewController however I am able to use it. I am trying to save integers and floats to properties I have set up in the AppDelegate (a big no-no I know, but this is a project for an introductory class and I'm not expected to get too advanced, especially since everything we've done so far is not compliant with the MVC paradigm). The app uses a toolbar to switch between views using the app's ViewController to load the other ViewControllers as subviews. I was going to put the AppDelegate declaration and update statements in the ViewDidUnload method of each view controller, but I'm not sure that the Views are unloaded whenever they are switched (they're switched by removing the current View from the SuperView and loading the new one as a Subview at index 0). What happens to the views that are not currently being viewed then? Is there a method that detects that that I could implement the AppDelegate declaration and updates into?
I guess ideally I'd like to be able to access the AppDelegate object in any method in my ViewControllers because I have a lot of quantities being updated throughout and would like to have those quantities updated in the AppDelegates values as soon as they happen, since I'm not sure what happens with a View is cleared from SuperView
Thanks in advance everyone
You can access your app delegate via [[UIApplication sharedApplication] delegate] from anywhere in your application.
You should never instantiate another copy of the object on your own. The system does this for you at startup.
As for detecting changes, you can override the viewDidDisappear method of UIViewController. (You're correct--in general, they will not be unloaded when switched, and viewDidUnload will not be called)

Adding object to NSMutableArray in another xib

Im trying to add an object to a NSMutableArray in another xib. But seems isnt working. What im doing wrong?
Thanks!
-(void) buy {
CartViewController *carrinho = [[CartViewController alloc] initWithNibName:#"CartViewController" bundle:[NSBundle mainBundle]];
carrinho.produtoCodigo = [[NSMutableArray alloc]init];
[carrinho.produtoCodigo addObject:#"aa"];
[carrinho release];
NSLog(#"did");
}
Your code looks fine so far. Make sure the connections in InterfaceBuilder and the File's owner in the XIB is set correctly.
Ok, several things. First you don't need to pass in [NSBundle mainBundle]. nil works fine if you want the main bundle. Second issue is, produtoCodigo should be a property set to retain and as such you should pass in an autoreleased NSMutableArray i.e. [NSMutableArray array].
Thirdly, I would question why you would want to do this. It seems like a bad design. Ideally the mutable array should be an internal ivar in CartViewController. You should then have a method on CartViewController to handle the item. You should not care about how it is stored internally, only that you want to add an object to the controller.
If you want to pass in multiple objects you should have a method that takes an array of objects and pass that in.
Now finally, nibs don't really hold arrays, the class does. As such it shouldn't be an issue with your nib. The issue should therefore be with the class. Where are you checking whether the array is being updated and finding that it isn't?
you declare and create carrinho as a view controller, which should allocate and init the carrinho.produtoCodigo as well, if you have it synthesized. Then you alloc it again, which may be a memory leak. After adding the aa, you release it. Therefore, overall, you haven't accomplished anything. That mutable array comes into being, is modified, and then destroyed.
You mention "another xib" and from the name CartController and method name "buy" it sounds like you want to update a shopping cart that is being held by some other class. Therefore, the view or class with the cart (and mutable array) needs to be modified. It's like if you and a friend go shopping, and you delegate the job of managing the cart to him. He is the delegate, and only he can put stuff in the cart. Just because you want to buy something, you have to give it to him first so that he can put it in the cart. Right now, your code is like you grab something off the rack, but then put it back on the rack. It never makes it into the cart.
What you want to do is create a shopping protocol with a message addToCart which is what this code would instead do. It would send the message to the delegate to add the item to the cart. The other xib code has a method -(void)addToCart:(id)item; which is what is invoked when this code chunk does to call to the delegate. Look up protocols and delegates; they are simple to create, and the only way to get multiple controllers talking to one another.
Maybe you inserted this below code in the second XIB:
-(void) viewDidLoad {
produtoCodigo = [[NSMutableArray alloc] init];
}
because if you make allocate an array again, the previous objects in it will be removed.

How should I pass an array between view controllers?

I'm building an app that uses a TabBar controller in which one of the view controllers an NSMurableArray is set (and potentially modified). I then need to use that same array to populate a table on one of the other views when it is selected. I've looked into using a singleton (as was provided as an answer to this question on this website already) but haven't had much luck.
Would a singleton be the best way to go or is there a better way of doing it? I'd appreciate any help/examples if possible?
You have several options for doing this, here are 2...
1.) have the NSMutableArray be a property of the one view controller so the other one can access it like viewController1.mutableArray. To do just add #property (nonatomic, retain) NSMutableArray *mutableArray to your viewController class (using whatever name you want).
2.) Pass the array through a method from the first viewController to the other and keep a reference to that array in the other class.
You can 'attach' controllers to each other, just like you 'attach' ui elements to controllers. E.g., declare variable
IBOutlet ReferencedController *referencedMenu;
and then in Interface Builder draw a line between referenced and referencing controllers.
Do I understand you correctly?
Thanks for your help, in the end this is how I have done it:
UIViewController *tmpNamesListVC = [self.tabBarController.viewControllers objectAtIndex:1];
self.names = [tmpNamesListVC names];
When it builds i'm getting a 'UIViewController may not respond to -names' warning but everything compiles and runs as it should.

how to load a view using a nib file without using view controller

i am new to this objective-c
i want to load a view using nib file i created when i press a button .without using any view controller..
This is generally considered a bad idea if you don't know what you're doing, but if you really want to do this then there's 2 places to look, depending on what version of the OS you're developing for.
iOS 4
Look at UINib in the documentation. You can use this to load a nib fairly easily.
iOS 3.2 and earlier
Use NSBundle. There is a category, documented under the name "NSBundle UIKit Additions Reference", that adds a method -loadNibNamed:owner:options:. You can also use this on iOS 4.0 if you so desire.
In both cases, the owner object fills in the role of "File's Owner" in the nib, useful if you have actions or outlets specified on the owner. The method also returns an NSArray of all the top-level objects in the nib. Be careful, if you use this array you need to retain any of the objects that you want to keep, as the array (and all the objects) are returned autoreleased.
Try this. Should show you how to implement your UIView subclass.
http://markuzweb.blogspot.com/2011/05/subclassing-uiview-with-nib-file.html

IPhone SDK: Using Interface Builder to link arrays

I´m trying to use Interface Builder (IB) to gain time in my app development. So I´m trying to do new things, for example, connecting objects between File´s Owners and Controllers.
The situation is:
1 - I have a ViewController with a Nib. This view controller have an array set as a IBOutlet.
2 - I put a custom TableViewController inside the Nib. Inside this TableViewController I set another IBOutlet Array, that I want to put as cell values (I will do this inside my TableViewController.m).
3 - The quesntion is, is possible to connect the two IBOutlets Array? Or to create something like a "IBInlet"..? Or in Interface Builder you can just use the IBOutlets as connections to the Library Objects of Cocoa Touch..?
Thanks for everyone..!
First off, I think it's unclear if you're trying to have two pointers to the same Array object or if you actually want to have two Array objects which you keep in sync. The latter makes little sense as it will just double your memory usage with no benefit, so let's assume you just want to have two pointers to the same Array object.
IB will help you link a data structure (your Array object) to a compatible interface widget, but it's still up to you to initialize your data structures in your code. Following that line of thinking, you can use IB to link your Array in the appropriate controller to the widget which you manage in that controller. Independently from that you can have one controller initialize the object and the other controller can get a pointer to that object from the first controller. Just make sure you manage your retains correctly ;)