Who calls the private method during unwinding in Xcode? - ios

For implementing unwind segue we need make control-drag in the storyboard and
create private method in the destination view controller.
I don't understand : if method is private, how it works? Because in the implementation file of my view controller this NOT calling.

When executed, your application parses the .storyboard file at first, getting to know what classes it needs to instantiate and other important information, like segue connections. Then, it creates class instances (and manages them later). Then, when requested (e.g. after a button press), it attempts to find a method unwindToList: in the controller instance. If there is one, it would execute. If not, an exception would be thrown.
However, that method is not exactly hidden. Basically, there is no such thing as a private method in Objective-C; at least not in the same way as some other languages have. Every method is accessible by the runtime. If you're interested in how Objective-C works exactly, take a look at these pages, for example:
How does objective-c handle method resolution at run-time?
http://cocoasamurai.blogspot.ru/2010/01/understanding-objective-c-runtime.html

Related

Calling functions from separate view controllers in swift

I think the solution to this is going to need to use delegation, but I'm unfamiliar with how to use them.
So in my project, I have my main viewcontroller/storyboard that contains a UIScrollView. That UIScrollview calls another storyboard (xib file) as a subview. The other storyboard (which is an xib file) is controlled with another swift file.
My question is, when I call an action inside of my other storyboard, how can I call a function from the main viewcontroller. Like say the viewdidload from the first viewcontroller.
I can't make the whole thing a global function, it needs to stay inside its class. So if I try to do ViewController.viewDidLoad() it needs (I think) an instance variable or something.
Thanks.
You can try:
Using weak variable (property) in the other class with type UIViewController
Assign the parent view controller to that property after the other view is initialized
Good reads about weak, strong, unowned references Here And Here
Firstly, if you want to call it with class name as you said above declare your method with "class". So its just like static in Java. It makes it generic to call it anywhere in your project. Make a separate extension.
class func myfunc(){
}
if you want to send data from B to A controller. You use what is called delegation. You give the work of B to A. Make a protocol above B for functions that you want to do or send with them. Call them in B. And then in A write code for those functions. So that you have the data from B to A
Else you demand something like common data. Create a singleton class and initialize properties methods there. You can use objects for that and call it in other controller to modify or make different instances.
You dont call viewDidLoad(). As the name says it loads once. If you want something that modify everytime you screen appears, use viewWillAppear

Swift 2 / XCode 7 - "EXC_BAD_ACCESS (code=2...)" when calling "ViewController().view" in another class

why is this error happening and what can i do to fix/prevent in the future? thanks!
NOTE: my other class is set up as such:
class Other {
//then all relevant funcs called
}
am i missing some basic setup information in order for this to run?
The formal explanation would be:
You're trying to access the view property before it was initialized. Another way to look at it is that you're trying to access the view property before it was loaded (in viewDidLoad).
Solution:
Depends what you're using that view for. I've never had to access another view controller's property like that. Consider exploring other strategies such as delegation, weak references to another controller, and passing variables in prepareForSegue if you need a reference from a view controller from another.

Objective-C method execution while object is deallocated - should I fix that?

In methodA of my view controller VC1 another view controller's (VC2) method methodB is called in which VC1 is deallocated. Then control returns to VC1 methodA which obviously crashes when self is used.
It is not obvious that the instance is deallocated, so developers may use self without knowing that they should not. From that perspective I'd like to fix the deallocation. However, I'd like to get some opinions whether or not such a situation is common or needs to be fixed ASAP a.s.o.
Q1: Is execution of deallocated object's methods somewhat common which one will encounter in typical medium projects?
Q2: Would it be acceptable, if comments are added, which warn the developer?
Q3: Are there any other recommendations / opinions?
The project is of medium complexity (about 200 classes of which 50 are view controllers). I'd like to get a feeling about how much effort I should invest to take care of such "deallocated method calls". If it would be one of my smaller pet projects, it would be rather easy to fix anything. However, with an inherited project which already went through a couple of hands, things are not so trivial any more.
EDIT:
didFinish delegate scenarios:
Thinking about it, I came across didFinish kind of delegate calls. Assume a master view controller (MasterVC) uses a slave view controller (SlaveVC) to do some work, keeps a strong reference to it and sets itself as a delegate for the SlaveVC. When the slave is finished, it calls slaveVcDidFinish. In MasterVC's implementation of slaveVcDidFinish the strong reference to the SlaveVC is set to nil. So when the slaveVcDidFinish returns, it is SlaveVC's responsibility to never use self, as it may have already been deallocated.
- (void) notifyDelegate
{
[self.delegate slaveVcDidFinish];
// From here on, `self` may be invalid...
}
This likely is relevant, when the SlaveVC is dismissed before the call to slaveVcDidFinish, as otherwise it cannot be deallocated because it is part of the view controller hierarchy.
Q4: Is my understanding of this didFinish scenario correct?
[/EDIT]
A few details, in case it is relevant:
VC2 presents VC1 and keeps a strong reference
VC1 does its work and needs to present VC3 for which it dismisses itself before
VC3 does its work and delegates back to VC1's methodA
VC1's methodA delegates to VC2's methodB
methodB releases the strong reference to VC1, VC1 now gets deallocated (dealloc is called), and control returns to methodA
methodA does a little more work and then returns
One way to do the little more work was to call methods on an object passed into methodA as parameter. That should work, as self does not play a role there.
Another way to do that work was to call a method of VC1 using self which obviously causes a crash. So as long as one does not use self, everything should be fine.
Yes, you should fix it, but based on what you are saying your app architecture must be to a greater or lesser extent wrong. You are trying to implement an algorithm distributed across view controllers that really needs an object that lives across the lifetime of the objects you are dealing with. Such needs a mediator object.
Actually I suspect you may not need to be implementing that algorithm at all and another approach that works better with how controllers are instantiated and how control gets passed around the app would work fine, but you haven't posted sufficient info for me to be able to advise on that.
However having said that, implementing an overarching controller could certainly be used to solve your problem. A good way to do this is often to subclass your current root view controller (or better still a subclass that implements a category you define). So for example, if it is a UINavigationController you are using, create UINavigationController subclass, change the class of it's representation in your Storyboard (assuming you are using storyboards) and do the work of coordinating display and dismissal of other view controllers in there.
Also check out the Mediator design pattern http://cocoapatterns.com/ios-view-controller-transitions-mediator-pattern/
As a note, generally these days you can avoid having any object properties for strongly holding view controllers. Usually the root view controller holds strong references to any view controller it needs to present, lazy invocation should be used to present view controllers that are not currently presented or stored in an existing navigation controller stack (which keeps the memory utilisation profile in good shape) and any other child view controllers can be added in to your view controller heirarchy using the addChildViewController: method in which case they are strongly held in the childViewControllers array property.
You may want a convenient name for a view controller, but actually I would recommend writing a small bit of code for as the implementation of any such property that will identify the controller you need from amongst those in the Apple supplied properties, and dynamically retrieve it. This may seem like hard work, but it's worth it and actually, paradoxically, decreases code complexity and helps ensure you stay working with the view controllers the way Apple intended. Doing anything else increases pain.
Using separate object properties for holding references to view controllers will usually only duplicate mechanisms the existing Apple classes already provide you with. Such unnecessary duplication increases code complexity and can introduce bugs and memory management issues (of the kind you are in fact describing).
Sorry this answer is quite general, but you are seeking an answer to the wrong question. From what you have said it's clear that at some level you need to address your app architecture.
I agree the architecture seems flawed but as you say it is inherited code and not trivially small maybe some compromises must be made.
I am thinking since self (or any instance variables or properties) cannot be called anyway perhaps you could make the methods you need to call class methods (+) rather than instance methods (-). Class methods are obviously safe to call without an object instance.

Not able to get the video if the stream is created first in OPENTOK

I am basically trying to implement a video conference functionality using opentok.
I have two view controllers.
Class A that has a grey image(to tell user is offline).
It calls setsession from class B to establish the session.
uses ClassADelegate and implements setUserOnlineImage that sets the class A grey image to green.
Class B holds a method useronline.
Has a class method sharedinstance that gives out the singleton instance of the class
viewdidload ->sets a variable type = 2;
setsession ->sets a variable type = 1;
It also has a protocol "ClassADelegate"
Protocol ClassADelegate has method setUserOnlineImage.
Has a callback method session:streamCreated: that is called when a subscriber is created and setupPublisher that publishes the video
The flow is like this.
first Class A calls the setsession from Class B to establish session.
Then when a connect button is clicked the viewdidload is called and then the setupPublisher is called, view is modified loaded and all that.
Now when a subscriber tries to connect session:streamCreated: is called. here when i try to print type value it comes as one, likewise many other variables also become nil which inturn results in just giving the audio and the video isnt seen.
where as if first session:streamCreated: is called (first video is received and then connect is clicked) the flow works fine and the print statement in session:streamCreated: correctly prints type value as 2.
Someone help me figure out whats happening.
I want to know why the type value is getting changed & various other variables become nil. This is preventing the video from showing. Am i missing something? Is any other instance is been taken(but I am using a singleton instance)?
The flow you describe doesn't follow any of the known patterns of how UIViewControllers should behave. Specifically, you shouldn't need to use a singleton instance of a view controller. I think you need to reconsider the architecture, specifically the relationship between these two view controllers.
By the way, the viewDidLoad method is called on the view controller as soon as its view property becomes available, which can be before its on the screen. If the view controller is loading its view from a storyboard or nib, viewDidLoad is called as soon as that view is ready. Otherwise if you are implementing loadView, viewDidLoad is called after that method is finished.
Can you describe what Class A and Class B are trying to accomplish? It sounds like Class A is a view controller for some type of status view that shows a user's online/offline status. Class B sounds like its the OTSessionDelegate as well as the view controller for where the publisher/subscriber views will be placed. Why are these not the same View Controller? (generally view controllers are meant to control a "screenful" of content, unless you are using View Controller Containment). If these two view controllers are not on the screen at the same time, can you use a segue to pass data between them when the transition occurs?
UPDATE:
The additional information is useful for me to give you a recommendation. The thing I'm still uncertain about is if you actually do have these 2 view controllers' views on screen at the same time. This solution should work in both cases.
Outside of a segue, one view controller should not really be calling another view controller's methods directly (so calling setsession as you described is a bad idea). You shouldn't even set one as the delegate of another. At most they should share a Model object to communicate. The OTSession can be seen as a Model object. The challenging limitation is that when using the delegation pattern, only one object (you chose Class B) can be informed of updates. Rather than using the delegation pattern, I think you should use NSNotifications. In order to accomplish this, you should "wrap" the OTSession model in your own model object, setting your own model object as the delegate. Then you can notify both controllers of interesting changes as they happen. I've created a diagram to demonstrate:
In this diagram, all the downward solid arrows are owning references. VideoConference would be your own class and it would implement the OTSessionDelegateProtocol. On initialization, the VideoConference instance would create and own an OTSession instance. When something happens that Class A or Class B need to know about (such as the remote user coming online), VideoConference can send an NSNotification, which both controllers can be observers. Here is a useful article about NSNotifications.

xcode using view in subclass

I am learning to program the iphone and I wanted to do some drawing. I followed some example code and subclassed the viewcontroller and it worked fine. Now as I wanted to expand the program I came upon a design question that I could use a little help on.
I subclass myviewcontroller with mynewview. If I have any code in the myviewcontroller how do I call or reference it in mynewview and vice versa? I am not sure if I am asking this right but I am trying to understand the relationship between the class and subclass.
Objective-C objects benefit from inheritance. All classes are subclasses of NSObject, therefore you can call init on any object. If you created a custom class and gave it a method doSomethingAwesome, you are free to then implement doSomethingAwesome in any subclass of your custom class. However, declaring a method in a subclass does not add that method to the superclass. As an aside, I rarely find myself subclass sing my own custom classes. I believe that it is encouraged to maintain what is called a shallow object hierarchy. Usually I subclass the stock cocoa classes, customize to my needs and if I need custom methods in more than one subclass I will declare a category on the superclass rather than relying on inheritance to provide my custom behavior
The messaging system in Objective-C is dynamic. Every object includes a struct with information that the runtime use for introspection. Here the runtime will find a list of methods the object is able to respond. So, let's say you message an instance like this:
[mynewview someMethod];
The runtime will first check the object information to trying to find some method that will be able to respond the message. If nothing is found, then will query the super class, and so on. In fact, the runtime is much more complex, and will give any object more opportunities to respond (that's the dynamic part. For instance, mynewview might not have any method called someMethod and yet, might be able to satisfy the call, but that's something you might not want to worry right now).
From a child class you can call the superclass implementation of a given method with the keyboard super, so if mynewview is a subclass of myviewcontroller you can call myviewcontroller implementation from mynewview with:
[super someMethod];
If someMethod is both present in myviewcontroller and in mynewview, the runtime will automatically only call the child implementation, you have to call the parent implementation (if you have to) from the child implementation.

Resources