Can I make a UIControl take ownership of "disposable" event targets? - iphone

In my view controller I'm programmatically creating N buttons in my UIView. Each button needs to do something different, so I've made a custom handler class, which I create N instances of, each initialized with custom data. I create them in the body of a for loop and add them as targets, after which I don't need them anymore.
However, because UIControls don't take ownership of their event targets, I need to hang on to these custom handlers myself (in the controller), introducing an extra ivar and the necessary release code. Is there a more elegant way to handle this problem?

Add those custom handlers to an NSArray that you retain in your controller (whatever controller is creating the buttons). Adding an object to an array retains it, so you will know that it is always around.

Associative references?

Related

How do I keep an object created within a method alive in objective-c?

I want to place multiple pie charts in my application that I create using core plot. I made a wrapper class (lets call it PieChartViewController) that is a view controller and sets up the graph and some buttons and actions to make the graph interactive. To deploy it, I usually just create a property on another view controller that holds the PieChartViewController and when I am initializing this view controller I simply alloc/init thePieChartViewController and add its view to the main view. This usually works fine.
The problem is that on another view, I want to add a variable amount of graphs to the view and this number is decided when the view controller is initialized. I have a method that initializes each PieChartViewController and adds it to an NSMutableDictionary on the parent so that I could keep a reference to them. However, this doesn't seem to keep them alive because I always get BAD_ACCESS 2 crashes and when running instruments I realized that they get deallocated.
So when the PieChartViewControllers are stored on a property it's all good, but when I put them in a dictionary they seem to not be kept alive long enough. I am still not very familiar with memory management in objective-c and I'm not really sure how to go about this, would appreciate any help.
I simply alloc/init the PieChartViewController and add its view to the main view. This usually works fine
It may work fine, but don't do it. This is a misuse of UIViewController. See my answer here: https://stackoverflow.com/a/15962125/341994

Passing NSString from one ViewController to other's VC NSMutableArray

I'm a starting iOS developer and I would like to get the idea of NSMutableArray.
Specifically, I want to pass NSString value from one VC to NSMutableArray, belonging to another view controller. I also want that NSMutableArray to populate UITableView on its view. Any ideas how to do this?
For example, I have this action that the user triggers from within 1st view
- (IBAction)addToFav:(id)sender {
}
And I want to pass a value of NSString myBookString to the NSMutableArray array in the 2nd view.
The task is fairly simple, but I can't quite understand why you can't pass the values to NSMutableArray outside this - (void)insertObject:(id)anObject atIndex:(NSUInteger)index method mentioned in Apple's reference docs.
Thanks in advance!
EDIT: My views are different VC belonging to UITabBar and to UINavigationController at the same time
You need a communication between two controllers. There are several solutions. Pick one of the following. I recommend delegate.
From http://www.hollance.com/
When you have two objects A and B, say two view controllers, that you want to make talk to each other, you can choose from the following options:
NSNotificationCenter.
This is anonymous one-to-many communication. Object A posts a notification to the NSNotificationCenter, which then distributes it to any other objects listening for that notification, including Object B. A and B do not have to know anything about each other, so this is a very loose coupling. Maybe a little too loose…
KVO (Key-Value Observing).
One object observes the properties of another. This is a very tight
coupling, because Object B is now peeking directly into Object A. The
advantage of KVO is that Object A doesn’t have to be aware of this at
all, and therefore does not need to send out any notifications — the
KVO mechanism takes care of this behind the scenes.
Direct pointers.
Object A has a pointer to Object B and directly sends it messages
when something of interest happens. This is the tightest coupling
possible because A and B cannot function without each other. In the
case of view controllers you generally want to avoid this.
Delegates
Object B is a delegate of Object A. In this scenario, Object A does
not know anything about Object B. It just knows that some object
performs the role of its delegate and it will happily send messages
to that delegate, but it doesn’t know — or care — that this is Object
B. The delegate pattern is often the preferred way to communicate
between view controllers, but it takes some work to set up.
Blocks.
Essentially the same approach as delegates, except that Object B now
gives Object A one or more blocks (closures) to be executed when
certain events take place. There is no formal delegate protocol and
the only thing that Object A sees of Object B is the blocks it is
given.
NSMutableArray is just that, a standard mutable array implementation. It has all of the functionality you would expect from one in any other language/framework. docs.
What is the problem with the way adding elements to an array works? You can also just do [array addObject:object] if you don't mind adding it to the tail.
To answer the rest of your question, there are many ways to transfer data from one controller to another. How is your navigation set up? Are you using a UITabBarController, or a UINavigationController? How are the views related to each other? If they are nested, you can pass data directly from one to another. If not, you could use something like your app delegate to hold the data and pass it around.

creating a reference for use in identifiying if a button was clicked

How is it possible create a reference for an uibutton to check if it was pressed and do something like make the value for that button true in order to be able to use that value later on. I heard of ivars but i havent seen any documentation on how to use them and im not sure if they would work for my ibaction uibutton...
This is really a fundamental question and a full explanation will take along time.
Basically, you need to understand the concept of MVC (Model-View-Controller). In this case, the "View" will be your UIButton created in Interface Builder. It needs to have a target/action setup to point to some "Controller". This will be a custom class you design that performs some action when the UIButton is released. This controller can also track finger up/down/move/drag and what not. This Controller will store the fact the button was pressed in a "Model" class.
Here is some more reading:
http://developer.apple.com/iphone/library/documentation/general/conceptual/devpedia-cocoacore/MVC.html
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html
In the simplest cases, this can be done with Core Data and IB without writing any code and simply making connections.

Passing Several NSStrings to another view - Iphone

In my iPhone app, the user will be making multiple NSStrings. Once these are made, I need to pass them to another view completely in the app. How can i do this? All I know at the moment os I can't access objects or variables declared in one view, in another. Thanks.
One way would be to follow the MVC (model view controller) design pattern. Whichever controllers are responsible for your respective views can then store and retrieve the NSStrings from/to a common data model object.
As to how you can make the strings stored in an object visible to the outside, the easiest way is to use Objective-C properties to save you from writing the accessor methods yourself.
I hope this helps with your problem or at least gets you started in the right direction.
Place the strings in a data model object (the M of the MVC pattern), with accessor methods (getter and setters, which can be automagicly created by properties). Then create and place that model object in some central location, a controller common to all views requiring that data, or the appDelegate, a reference for which can be found from any view.
Josh,
I would add to the MVC thing, that still you can do this in several ways.
What I would do for example, is to make your other "View Controller" (MVC), to "observe" when does the user create a new string, and to fetch it accordingly. In that way you would reduce coupling and it will be a cleaner implementation.
Another way would be to create a "delegate" so that the First View controller, "notifies" or calls the delegate method that you created, each time the user creates a new string ( again reducing coupling )

Passing variables through classes in Objective-C

In my scenario I have 2 view controllers, one tied to the main view and one that is connected to the first one as a subview.
Now let's say that my App Delegate class wants to pass a string to the subview controller. What is the best practice to achieve this? If I wanted to pass it to the 1st controller i could just say something like
[self.firstController getStringInCustomFunction:[NSString stringWithFormat:#"200%d", 9]];
Also keep in mind that this call might have to be asynchronous.
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Take a look at NSNotificationCenter.
Specifically, postNotificationName:object:userInfo, wherein you create an NSNotification that includes an NSDictionary of objects you pass inside userInfo.
On the other end, you have another object that is registered to "hear" an NSNotification of a specific name. That other object calls whatever method is specified in the registration. You might unpackage the userInfo dictionary in this method, to retrieve the object of interest.