ov1d1u
ov1d1u

Reputation: 1077

ARC and ViewControllers

I have a little misunderstanding regarding ARC. I'm creating a new UIViewController using the following code:

    CGRect screenRect = [[UIScreen mainScreen] bounds];

    LocationProfileView *locationProfile = [[LocationProfileView alloc] initWithLocation:l];

    locationProfile.view.frame = CGRectMake(0, screenRect.size.height, screenRect.size.width, 400);
    [appDelegate.window addSubview:locationProfile.view];

    [UIView animateWithDuration:.25 animations:^{
      locationProfile.view.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
    }];

In its UIVIew I put a button which removes the view from screen. The problem with this is that locationProfile gets deallocated immediately after its being added to screen, so everytime I'm trying to tap on "Close" button (which calls a method in LocationProfileView class) my application will crash.

So I added a property:

@property(nonatomic, strong) LocationProfileView *locationProfile;

and changed the second line of code in:

locationProfile = [[LocationProfileView alloc] initWithLocation:l];

but now my class won't be deallocated until I initiate it again (because it loses the reference to the first instance of LocationProfileView?). What should I do to make my class being deallocated every time I tap on "Close" button? I guess that setting locationProfile to nil would work, but this means that I'll have to call a method in the main class (the one which contains the code block).

What is the proper way for doing this? Sorry if my questions is too noobish.

Note: l is an instance of a custom class which contains some infos to be displayed in LocationProfileView's UIVIew.

Upvotes: 1

Views: 109

Answers (2)

Mark Bernstein
Mark Bernstein

Reputation: 2080

In your original example,

LocationProfile *locationProfile=...

is a local variable. So it's released as soon as you return from the constructor. That's what you observed.

When you make it a strong property, the view controller retains the locationProfile:

 @property(nonatomic, strong) LocationProfileView *locationProfile;

Upvotes: 1

tzl
tzl

Reputation: 1590

- (void)closeButtonCallBack {
    [self.locationProfile removeFromSuperview];
    self.locationProfile = nil;
}

i am assuming the target of your close button is the viewcontroller itself

a strong pointer will the retain the object until the viewController itself is deallocated, unless you assign to it nil

a local variable will be deallocated when it goes out of scope

ALTERNATIVELY

without using the strong pointer, you can do this

LocationProfileView *locationProfile = [[LocationProfileView alloc] initWithLocation:l];

UIButton *close = [UIButton buttonWithType:UIButtonTypeRoundedRect];
close.frame = CGRectMake(0, 100, 100, 30);
[close addTarget:locationProfile action:@selector(removeFromSuperview) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:close];

Upvotes: 2

Related Questions