If we create many IBOutlets from the storyboard/xib to the ViewController/View then will it cause performance overhead? If so how?
See the IBOutlet Definition in Apple Developer.
Here's Outlets documentation link
We can see this
the more outlets an object has, the more memory it takes up.
If there are other ways to obtain a reference to an object,
such as finding it through its index position in a matrix,
or through its inclusion as a function parameter,
or through use of a tag (an assigned numeric identifier),
you should do that instead.
So it will cause performance overhead.
For more details, you can see the documents.
Yes. That's why you should create many storyboards base on your purposes.
For example : Setting Storyboard, Main Storyboard, User Storyboard, Picker Storyboard.
Related
We can add UITableView delegate and datasource to UIViewController via storyboard and programmatically, so i want to know that is there any difference in app performance using one of this methods.
Of course a UITableView has only one and the same delegate and dataSource property.
So the difference is what sets them: your code or the iOS code that instantiates a storyboard. Execution of both is similar in performance.
But a storyboard is a textual file that needs to be processed at run-time before the iOS code to set the properties will be executed. When you set these table properties in the storyboard, this adds a little processing work.
Since iOS is very fast at processing storyboards, the additional time for these two table properties is negligible.
You should therefore not worry about performance and just do what you'd prefer.
No there is not any difference in terms of app performance. It is just a matter of preference.
I have multiple storyboards in my project, each having an almost identical view controller (only dimensions are different). The storyboard used depends on the device in use. What I want to do is have the equivalent element from each storyboard under the same IBOutlet. This way, whatever I do to an element in the storyboard being used, the same would be done for all other storyboards. This is instead of creating an IBOutlet for the same element in each different storyboard.
For example, we may have two buttons, one in each storyboard. They are meant to be the same button but in different sizes, I set this button's alpha to 0 at one point the in Swift file. How could I do this for both buttons under one name (the same IBOutlet)? I know this means doing something on a storyboard which isn't even being used and therefore not accessible on the device, and I'm not sure whether it'll spit up an error or not. Surely this is a way around this though, because there are apps which use multiple storyboards.
I could imagine possibly stating if (storyboard == xnamex) {execute code for specific storyboard}, but this would mean having multiple if statement with the whole code repeated for different storyboards, and having to create an IBOutlet for each element, which is unrealistic. How would I get around doing this?
Many thanks.
If it's exactly the same button except as you mention the size on it. You can just pull an outlet to the same name and they both will be contained in there. As mentioned [Multiple buttons connected buttons best practise you pull the outlets to the same place and then action to the same place as well. However. Sometimes the action can be tricky, if you get problem there, just create a new action with the exact same name and then remove it. It will still be connected to the same name.
in my project I have a big amount of IBOutlet and var inside one swift file. Do u have any suggestions how to organise well this list? or categorizing in some ways? thanks
I think you can use tag to organize it or sub-class these components, add some properties as type, category, ... to handle it easier. Anyway, please carefully when you use tag.
I can just advise you to add //MARK: explain the section content to let other dev understand your organization
It depends on the content of this swift file, but usual it's a code smell.
Try to differentiate and separate variables and functions by their responsibilities.
If you have tons of IBOutlets in a single file, that could mean that possibly you are making a bad code in general. Try to divide and organize UI elements on custom subviews. For example, if you are making a chat view controller, you can split one big view to two subviews named ChatView and NewMessageView. The first one will contain and manage messages that was sent. Another one will provide a text field with "send" button and another elements like a button to upload a photo, etc.
You are free to make IBOutlets in UIView, not only in UIViewController.
Is it possible to use predefined constant values in Interface Builder?
eg. If I define MyConstantWidth = 10; in a header file, can I then use it in IB? I expect it doesn't work but maybe somebody has a clever solution.
As far as I know Interface Builder is a one-way ticket.
You can only feed the .m with information (via runtime attributes) and you can't use info from your .m/.h to feed the IB.
Conceptually, placing values in your code to use in IB goes against the whole idea of separating visuals from the coded logic.
I do recognize that using "named" values within IB would be helpful to maintain consistency and facilitating updates. Colors are my personal pet peeve on this front.
If you aim to programatically change attributes that merely have an initial value in IB, outlets are probably your only option.
You can also use a hidden controls or low priority constraints to express an arbitrary value that you map to via an outlet. I use that sometimes to toggle between constraint values by creating two additional low priority constraints and copying their .constant value to the high priority one when appropriate. This keeps all the values in IB and close to each other (and more importantly out of the code).
A while ago I became a fan of creating/manipulating the view hierarchy through code. Both because I think is more expressive and forces me to learn more about Cocoa.
But I just wrote a 5 lines of code which would look way more expressive if an IBOulet was used. It finds a subview within a view with a specific tag and sends a message to it. But I could easily create an IBOutlet and do it in one line only.
Because of this, I ask: is creating an IBOutlet too expensive?
P.S.: Let's cut off the "readability over performance" for now. I really want to know the impact of this.
IBOutlet is a marker for Xcode that gets removed by the time the preprocessing step is over. Internally, setting it up boils down to assigning a single pointer to an instance variable that "backs" the IBOutlet property. This pointer is assigned at the time the view is set up, and does not change after that. It is very cheap.
Finding a subview by tag, on the other hand, is a run-time operation that needs to run every time that you are looking for the subview. Usually it is cheap, but it may become considerably more expensive in a view with large number of subviews that have subviews as well.
Therefore, I would definitely go for IBOutlet, because it's a one-time deal, and because it lets you shorten the code from five lines to one.
You have to be able to find out the pros and cons of your current approach. In fact Apple's documentation states:
As with any item of object state, you should be able to justify its inclusion in a class; the more outlets an object has, the more memory it takes up. If there are other ways to obtain a reference to an object, such as finding it through its index position in a matrix, or through its inclusion as a function parameter, or through use of a tag (an assigned numeric identifier), you should do that instead.
I prefer to use IBOutlets in most cases, as (I know that you don't want to hear this) they make the code more readable and of course as #dasblinkenlight pointed out, your traversing of the view hierarchy is performed at runtime and therefore anytime (assuming you do this in viewDidLoad) the view is loaded.
My recommendation: Stick to IBOutlets, unless you have a really really simple view hierarchy and using tags to find your subviews is the best solution.