App delegate allocated object displayed in multipl

2019-08-17 03:49发布

问题:

I'm in a bit of a pickle here.. Building an iOS game that contains lets say two views: BaseView and MapView. Now, these of course has the same appDelegate.

These both use an UIView subclass called rivbox. In earlier builds, I allocated an instance of rivbox in both the Base and the Map-view. When I realized that I'll have a lot of subviews using this rivbox I instead chose to allocate just ONE instance of rivbox in the appDelegate and then, when a subview is loaded is gets to "borrow" the rivbox from the appDelegate by using these nifty functions.

-(void)viewDidLoad {
//Get all the sweets from the parent!
    appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    rivbox = appDelegate.rivbox;
    [self.view addSubview:rivbox];
...
}

And this function is for updating the ownership if we return to this view again

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if(rivbox != nil) {
        [rivbox setDelegate:self];
        [self.view addSubview:rivbox];
    }
}

This works fine! I find the rivbox in the appDelegate and it's updated! When I move to another view it loads there too just fine! But when I move back to the first view this seems to be leaking?!?! I can't see the rivbox in my previous view when I return to it even though the previous view now owns it!

Problem is: What is wrong with this? Do I really have to add rivbox as a subview every time I return to a view that's already been loaded? If i remove that string then I can't see the MyBox when I return to a prior view.

回答1:

This is really poor practice. If you're referring to the app delegate in any class you probably need to rethink what you're doing.

From Apple's docs:

The app delegate is a custom object created at app launch time, usually by the UIApplicationMain function. The primary job of this object is to handle state transitions within the app. For example, this object is responsible for launch-time initialization and handling transitions to and from the background.

Referring to the App Delegate for anything else is like using global variables. It seems like an easy short-cut at the start, but can quickly end up a confusing mess as your code base grows.

The app delegate is what it says - the delegate object of UIApplication. The views you're creating have nothing to do with UIApplication, so shouldn't be anywhere near it's delegate.

Design and build simple, self contained classes that encourage re-use. In the long term you'll be glad you did.

What advantage do you perceive by creating this single rivbox?



回答2:

It should be enough to do this in both controllers :

- (void)viewWillAppear:(BOOL)animated {
  //Get all the sweets from the parent!
  appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  [self.view addSubview:appDelegate.rivbox];
...
}