1
votes

By default, UIView returns its UIViewController in nextResponder function - if it has one. I think UIView must have hold an reference to the UIViewController.

If so, won't it lead to a circular reference between them, since UIViewController also holds an reference to UIView?

--- update -----------

I notice that the UIView has an private member named _viewDelegate, which is the UIViewController. Anyone knows how this is assigned?

enter image description here

--- update -----------

I found that when the view is loaded and assigned to the view controller, its _viewDelegate property points to the view controller at the same time. So this probably happens in the didSet event of view property.

According to the name of property _viewDelegate, it should be a delegate, which normally is a weak reference, I guess.

1
It's a weak reference.i_am_jorf
@i_am_jorf Where do you see that documented? What is the property to ivar name?zaph
I don't. I'm using my psychic powers. In general the delegate pattern requires a weak reference to the delegate. It may be that it is strong and they break the circular reference in some other way, after all, the view controller code probably predates ARC. Why are you so concerned? Are you experiencing leaks? Are you asking because you want to implement something similar and make sure you do the right thing?i_am_jorf
That just begs the question that there is no UIViewControllerDelegate. Where do you see any documentation that a UIView holds a weak (or other type) of reference to a UIViewControllerDelegate. UIViews do not have to have a UIViewController. My concern (I am not the OP BTW) is correctness.zaph

1 Answers

3
votes

Does an UIView hold an reference to its UIViewController?

A UIView might or might not hold a reference to a UIViewController, but this is an internal implementation detail. It is not documented, and should not be relied upon.

If so, won't it lead to a circular reference between them, since UIViewController also holds an reference to UIView?

This is a circular reference in the simplest sense, but that is not necessarily a strong reference cycle or retain cycle. That is, the internal reference could be weak or unsafe_unretained or manually set to nil at the appropriate time.

There might not always be a stored reference, though. Code like this can traverse the responder chain and find the closest view controller:

// self is the view

UIResponder *responder = self;
while ((responder = [responder nextResponder])) {
    if ([responder isKindOfClass:UIViewController.class]) break;
}
return (UIViewController *)responder;

(Code from UIView+PSPDFKitAdditions.m.)

The references you're seeing might be loaded lazily, or just be temporary cached values.