UIStoryboard UIView controller - ios

In published my app with a UIViewController connected to the main .h file in Storyboard. The controller can not be reached in any way (it is not connected with a segue to any other view controller. My doubt is: Does this controller take up memory? The codes don't run if the controller is not opened, or am I wrong??

When your program is loaded, an instance of UIStoryboard is created, which loads the storyboard file (a flat XML) and parses it. Therefore there is some memory that is associated with your ViewController. However, until the ViewController is not loaded, it is neither allocated nor instantiated.
That said, you can load UIViewController from the storyboard without connecting it with a segue. This is done using the Identifier of the UIViewController with the Method -instantiateViewControllerWithIdentifier: of your UIStoryboard.
If this does not happen in your code, the only memory the definition of the UIViewController causes is associated with the instance of your UIStoryboard.

Related

Properties return nil when a UIViewController is not being presented

If ViewController1 is not being presented but ViewController2 is: I can easily update GUI in ViewController1 from ViewController2 but I cannot retrieve any values in ViewController1 while ViewController2 is presented. When ViewController1 is not being presented it always returns properties as nil.
In my case, each view controller is being presented on a tab bar view controller.
What would be the best way to go about solving this?Thank you.
The nib file you specify is not loaded right away. It is loaded the
first time the view controller's view is accessed. If you want to
perform additional initialization after the nib file is loaded,
override the viewDidLoad method and perform your tasks there.
This is from documentation regarding to initWithNibName designated initializer :https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instm/UIViewController/initWithNibName:bundle:
EDIT based on the comment from :
If you are using UITabBarController, it has a viewControllers property so that all retain count of your view controllers is not decreased to 0 which have not been deallocated. If you found anything nil, then it should be some problems in your initializers.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITabBarController_Class/#//apple_ref/occ/instp/UITabBarController/viewControllers
You should not have your own mechanism to access view controllers. Instead, use viewControllers property from UITabBarController because it helps managing valid view controllers.

performSegueWithIdentifier replacing detailViewController works, but prepareForSegue is not called

I have an app created from Xcode 4.5's boilerplate Master-Detail Application with CoreData, StoryBoards and ARC turned-on that is not calling prepareForSegue. CoreData isn't currently being used, but it will be to cache XML responses. performSegueWithIdentifier works, but prepareForSegue isn't and I'm having troubles passing/access data from the MasterViewController to/in the detailViewController created by performSegueWithIdentifier.
My basic set-up is similar to what's discussed in the thread: Storyboards and UISplitViewControllers. There's an image of a storyboard on page three that's very similar to my set-up (I don't have enough rep to post images).
In a nutshell:
I create a standard splitView arrangement
The MasterViewController builds the main table
Each cell corresponds to a URL that returns XML data that determines what's in the detailView
The fetched XML is parsed using a NSXMLParser operation/class
The fetched XML determines which detail view is needed and the MasterViewController calls the appropriate 'replace' segue (via performSegueWithIdentifier) to kick-off the corresponding detailViewController to display the fetched XML
The problem that I'm having is that prepareForSegue isn't being called, so I can't pass the fetched XML to the detailViewController.
What I need is one of the following:
prepareForSegue to be executed
a way to know segue.destinationViewController inside handleLoadedResponse:notif
a way to get access to the "currentResponse" variable in the MasterViewController from inside the viewDidLoad method of the detailViewControllers
a way to find the MasterViewController via its StoryBoardID
What I've tried:
Putting NSLog() statements in each viewController's prepareForSegue -- none of them are called
Digging through the self.parentViewController chain in the detailViewController to find the MasterViewController that called performSegueWithIdentifier -- I can't find the class variable I'm looking for
Read pretty much every "prepareForSegue not called" post I could find -- They all seem due to some coding/storyboard error that I don't see in my code/storyboard
Could the problem be that I'm calling:
[self.navigationController performSegueWithIdentifier:#"theDesiredSegue" sender:self];
from inside the handleLoadedResponse:notif call-back and the app is trying to call prepareForSegue in my parsing object?
TIA
Ray
Well, chalk this up to staring at the code too long and/or newbie-ness.
After triple-checking everything that I though was obvious, I thought the only thing left was that the segue code didn't behave correctly inside the NSXMLParser call-back, so I switched the handleLoadedResponse:notif routine to store the parsed data and send-out notifications.
While debugging those changes, I realized that my segues were attached to the wrong object. They were actually attached to the navigationController and not my viewController. Visually, things looked like the story board on page three of RWForums: Storyboards and UISplitViewControllers, but they really weren't. The end result being that even though it seemed like my code was calling performSegueWithIdentifier and that it's prepareForSegue method should have been called, it was actually calling the navigationController's segue, so the navigationController's inherited prepareForSegue was being called.
Recommendation: Make sure you re-re-re-check all the connections in the StoryBoard Editor with the Document Outline open.
Ray

UITableViewController being initialised twice

I was trying to modally present a UINavigationController with a UITableViewController as it's root view but kept crashing the app when pressing the button to present the modal view.
- (IBAction)flipToDefaultsViewController:(id)sender
{
RootTableViewController *controller = [[RootTableViewController alloc] initWithNibName:#"RootTableViewController" bundle:nil];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:controller];
nc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:nc animated:YES];
}
The app crash with the message:
[RootTableViewController numberOfSectionsInTableView:]: message sent to deallocated instance 0x5677b5
When I loaded up Instruments to take a further look it was apparent that two instances of my UITableViewController were created, one with the owner of the UINavigationController and the other by UIKit. The UIKit created instance was the one that was deallocated and causing the crash.
When I changed the initialisation from initWithNibName:bundle: to init the UITableViewController loaded fine (my .xib file was the same name as the class).
My question is why would this happen?
Should you not initialise a UITableViewController this way when adding it to a UINavigationController? I've had a hunt around the documentation with no joy so far.
Using iOS 5 with ARC but target deployment is 4.0.
I haven't worked out why the object was being initialised twice, however I did review the steps that I used to create the .xib file and it looks like there is a problem with copying a view from a Storyboard to Interface Builder. In hindsight this makes sense, but as the view appears to copy without error and everything else seems to look okay it's easily done.
It would appear that similar problems were experienced by others with similar results.
By creating a completely clean subclass of UITableViewController with a nib file (⌘-N) and copying code from the initial class into the new one I'm able to use the initial code above to alloc/init my modal view.
BTW I was mistaken in my opening post about the nib file loading correctly when using init. It wasn't and in fact this behaviour doesn't happen for UITableViewController apparently where as other classes having a class name the same as the .xib file will attempt to load the .xib first.
If this is a button, than you should not initialize anything when the button is pressed. You should initialize beforehand and simply present the modalViewController when the button is pressed.
Is there any reason why the rootViewController and the navigation controller cannot be initialized in the appdelegate didFinishLaunchingWithOptions method?

Accessing a created instance of a viewcontroller

I have a MainViewController and by using prepareforsegue I pass data to my NowPlayingViewController. When I select audio in the MainView everything I need to be pushed is pushing successfully to the NowPlayingViewController, but after going back from the NowPLayingViewController to the MainViewController I have no way of accessing the NowPlayingViewController without selecting a new audio file. From what I understand, when using storyboarding and segues, it automatically creates a new instance of the view. So my question is, how would I have a button on my MainViewController that could access the last instance of NowPlayingViewController?
try overriding - (void)willMoveToParentViewController:(UIViewController *)parent in your NowPlayingViewController.
I'm not use to story board and segue so I might be off the track.
Have you try keeping a pointer to your NowPlayingViewController in your MainViewController? Or a pointer to your player? You could store it before pushing your NowPlayingViewController on the UIViewController presentation stack so you would always have the more recent one.

iOS storyboards instantiate viewController and IBAction

I may go mad very soon.
This is the reason:
- I started up with Single View Application project with storyboards. Then I set the view controller class name in the storyboard for my viewController.
- Next step I created one pointer for this viewController in AppDelegate method ...didFinishLaunchingWithOpt... and filled it up by calling [myStoryboards instantiate...]. It works pretty good because I can call method like [vc1 setMyName] which does smthng like self.myName = #"Johnny";
- But here it comes. When I create IBAction method joined with button, this method doesn't know anything about "Johhny". And this is because I'm in another instance. When I check the address of "self" it is another one...
WhyWhyWhy??? Please help, how can I use still the same object - the one instantiated in AppDelegate by storyboards and the one from storyboards in "interface builder".
Thank you.
Oh my. I think I really underestamated it...
When we were talking about getting pointer of other viewControllers from storyboard...
I have initialViewController got by calling rootViewContr... And another one connected with segue (modal) where is UITableView. A get data on rootViewController and I want to show them on the other one in the list (UITableView). So I call segue (performSegueWithIdentifier), the other controller is shown but the list is clear. Because the method I call is working with tableView variable which is null :/ Because, again, I'm in another object. That is because I call that method storyboard instantiate... How can I get exactly the same viewController which I'm working in storyboard with. It is quite confusing for me :/
I read something about prepareForSegue and getting the pointer by destinationViewController but that is not what exactly I want. I need the pointer before I call segue method and the viewController is shown...
Thank you.
If you've set up your initial view controller properly in the storyboard, you don't need to assign it to the windows rootViewController property in -applicationDidFinishLaunchingWithOptions: as this is done for you automatically. It sounds like you're creating a second instance. To access the original instance setup by the storyboard simply do this in -applicationDidFinishLaunchingWithOptions:
InitialViewController *viewController = (InitialViewController *)self.window.rootViewController;
viewController.myName = #"Johnny";

Resources