Does calling removeFromSuperview() on lazy created view instantiate it? - swift

In one of my view controllers, I have a lot of possible subviews that can be created based on the status of the data received. I am trying to make them class variables so they can be accessible throughout the file and am using lazy so that I don't create views I don't need. However, I need to make sure the views that could be displayed get removed if the status changes and would want to call .removeFromSuperview(). But I know that lazy variables get initialized the first time they get referenced and that would defeat the purpose of trying to save memory.

Yes, if you referenced the lazy variable in order to call removeFromSuperview, it would first create the view and then call removeFromSuperview on it. You should likely design another way, without lazy. I would recommend starting with the simplest approach (such as Optional properties, checking if it's nil, and creating it if necessary), and then extracting duplicated code. lazy solves one very specific problem in a very limited way. If you don't need precisely what it offers, you generally will need to build something custom

Related

Is it ok to use UIButton's .tag property for myself?

I realize that I can create a subclass of UIButton to add custom properties:
class myButton: UIButton {
var viewBounds : CGRect = .zero
...
}
However, at this moment I only need each button to store an Int, I am not using storyboards, and a lot of postings say that it's alright to use the tag property.
My question is, is this actually safe? Given possible future changes. etc. etc.? "Many postings" is not the same as an official answer, which I can't seem to find an answer to in the official documentation.
It depends on what you're looking to use the tag property for. From the UIView.tag docs, which you have likely seen:
An integer that you can use to identify view objects in your application.
</snip>
You can set the value of this tag and use that value to identify the view later.
The purpose of tag is to be an arbitrary user-settable property that you can use to differentiate between different views of the same type when you don't otherwise have a named reference to them.
UIKit itself will never set tag because the property is meant to be set by you, the app developer; however, that doesn't mean that some 3rd-party framework you're using is guaranteed not to stomp on tag values. Because tag lives in a "global" namespace of sorts (all code has equal access/knowledge to tag, unlike a property you might add yourself), different people might try to use tag for different things.
If you're creating view objects yourself, and managing the view hierarchy directly, then it's relatively safe to use tag. On the other hand, if you're getting views from another framework, or allowing another framework to manage views for you, it may use tag for its own purposes.
From your question, it appears the former is likely the case, but if you need stronger guarantees, you're better off adding another property which more directly identifies the views you'd like to be using.
You also haven't specified what you want to use tag for, necessarily, but if you just need to store an Int that's completely unrelated to identifying the button, I'd advise against using tag and instead add a semantic property that describes what you're trying to store. (Tags are also meant to be unique, which arbitrary data might not be.)

How to clean up "old" views using sap.m.routing.Router

With routing/routes defined in the manifest.json and using Router.navTo() to change the hash and the content of the target App control, I noticed that the "old" views and controllers are still hanging around and listening to events (e.g. performing binding updates for controls that are no longer visible on the stage).
I (wrongly) assumed that the router would clean these views/controls up for me - what is the recommended way doing so?
You are correct. Before calling oRouter.navTo(...) you can call unbind. To give you an example you could check here. There you can find the following line of code inside the onNavBack handler:
this.getView().unbindElement();
unbindElement() is called because previously bindElement(...) was called in the same controller. So just make sure to use bind/unbind combination before oRouter.navTo()...

Why we use app delegate in our application

I am new in iphone development and i needed a array which i use to access in different class so my senior told me that you should declare in App delegate and access it another class in which it require, so i wrote line for that
MyAppAppDelegate * appObject =
(MyAppAppDelegate*)[[UIApplication sharedApplication]delegate];
I done my task successfully but i couldn't get it 100%. Someone tell that why we use this and in what exactly situation in which we've to use this?
AppDelegate is loaded first when you run your application as it contains window. So, the variable and objects you want to access throughout your project is declared in AppDelegate. You just have to create an instance and you can access all the objects in AppDelegate.
ApplicationDelegate can be useful as a singleton class but you have to use it with discretion - and there are varying opinions on this - but if you have a few global type properties or methods you want to recall from various other classes, and I emphasize few, then ApplicationDelegate may be a nice place to add these.
And yes, it is bad design - but you can get away with it if you are prudent and as #Sedate Alien mentions, take a look at dependency injection.
The purpose of ApplicationDelegate, by the way, is mainly to handle events like loading your application, when you return to home screen, when you come back from home screen, etc.

CoreData Relationships in two different ManagedObjectContexts

Warning: This is my first IPhone Application and I'm new to Objective C, therefore my question might be very basic.
Actually I have a conceptual problem:
I have a one to many relationship between my NSObjects Project and WorkTime (Project<-->>WorkTime). WorkTime has attributes like startDate, endDate, … and a relationship named project to the Project object.
On the UITableViewController subclass that shows my list of WorkTimes, I fetch the CoreData Model with a FetchedResultsController. When I create a new WorkTime, I use a second context and merge it with the "default" once, once the user has clicked on "save" on the drill-down View, like in the CoreDataBooks example from the Apple Documentation. That works well.
The problem starts when I set the relationship. Since the projects are in the “default” context, I can’t assign any project object to the project key in WorkTime, since they are in two different contexts.
So, should I copy all the projects into the “saving” context? Or should I use just one context for everything?
One problem that arises when I use only one context is that the tableview that shows the WorkTimes gets actualized when the user clicks on the addbutton (insertNewObjectForEntityForName). So the list grows right before it presents the new view controller (addWorkTimeDetail) in modalviewcontroller. And if the user clicks cancel in that detail view and decides not to save the WorkTime, I’d have to delete the newly created entity from the context. I don’t think this sounds the way to do it.
Suggestions would be very appreciated!
UPDATE
I'm still having some issues:
When the AddWorkTimeViewController is created from the RootViewController, I create a new NSObject WorkTime. When the user clicks "cancel" I delete the newly created WorkTime and return to the RootViewController. The FetchedResultsController actualizes the tableView and I see a short animation that comes because the object has been deleted. That's doesn't look nice.
I know it would be better to create the object ONLY if the user clicks "save" and by "cancel" do nothing, but I need that object in order to populate the drilldown views with values. The drilldown views work with a NSManagedObject. I see two possible ways to solve this:
1) Have a temporary object TempWorkTime subclassed from NSObject with the same attributes from the WorkTime NSManagedObject. I would create the TempWorkTime in the AddWorkTimeViewController and use it for the drilldown views. I would of course have to subclass them to accept an NSObject instead of a NSManagedObject. I guess type casting wouldn't work. When the user clicks "save", I would create a WorkTime NSManagedObject and pass it the values from the TempWorkTime.
2) Is it possible to trick the FetchedResultsController so that it doesn't update itself while the tableView is not visible? In that case, it would not respond to the changes in the context until it's back in view, and so it would not do the delete animation.
Any suggestions?
SECOND UPDATE - maybe it's useful for people trying to do this same thing
I found this link which proved to be very helpful:
http://www.timisted.net/blog/archive/multiple-managed-object-contexts-with-core-data/
It's very well explained why it's sometimes a good idea to use two contexts. I had some problems with using one context explained in the UPDATE part of my question.
Now I'm using two contexts and it works perfectly, even with relationships. Important is to use the NSManagedObjects of the second context when creating the relationship. That was my mistake when I started to work with this approach.
I don't see why you use two different contexts.
The way to do it is to pass your tableView's context to addWorkTimeDetail, and add any new WorkTimes to that context. If the user cancels, i.e. doesn't create a new object, there will be nothing new in the list when you return. If the user creates the new WorkTime in the context it was passed, it will show up in the list when you return.
In your example, use only one context, and pass it along to your subviews.
I found this link which proved to be very helpful:
http://www.timisted.net/blog/archive/multiple-managed-object-contexts-with-core-data/
It's very well explained why it's sometimes a good idea to use two contexts. I had some problems with using one context explained in the UPDATE part of my question.
Now I'm using two contexts and it works perfectly, even with relationships. Important is to use the NSManagedObjects of the second context when creating the relationship. That was my mistake when I started to work with this approach.

Best practice for View-Routing in iPhone SDK

I've run into a little problem while developing a Core Data driven Quiz and be a bit confused about a best practice to solve my problem.
I have approximately five templates for the different questions, which will be loaded in case which question is displayed. So I check which template has question 1 and push the new question-template view into my navigation controller. Because its always the same code I want to write a function (I came from php) which gets the next question-id as argument and decide which template will be loaded and push the next view into the navigation-controller.
What is the best practice to solve this problem? Can I write a function with access to the navigation-controller, and my Core Data classes. And if yes where I have to create this function?
Okay I think I found an way but gets here another Error. I create a class called QuestionRouter and define an class method. I'll import this class into each viewController where it needed. The class method gets the correct template from Core Data without an problem. But now I wan't to load the correct view. For that I need to access the navigationController defined in my AppDelegate.
So how I can access the navigationController in my AppDelegate for another class?
Hope for an answer.
Mister-D