Reputation: 361
I have a scroll view in controller. The scroll view has one subview. The subview is an observer of the scroll view at the same time. I remove the observer when subview's willMoveToSuperview:
called. But when the controller dismissed, app crashed. Here are the sample codes:
@interface MyView : UIView
@property (nonatomic, weak) UIScrollView *scrollView;
@end
@implementation MyView
- (instancetype)initWithFrame:(CGRect)frame scrollView:(UIScrollView *)scrollView {
self = [super initWithFrame:frame];
if (self) {
self.scrollView = scrollView;
[scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
if (!newSuperview) {
[self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
self.scrollView = nil;
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
}
@end
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:scrollView];
MyView *view = [[MyView alloc] initWithFrame:CGRectMake(100, 200, 100, 100) scrollView:scrollView];
[scrollView addSubview:view];
}
@end
When I print self.scrollView
in willMoveToSuperview
, it shows null. When I change the property scrollView
in MyView to unsafe_unretained, app will not crash.
So I am confused. Why not weak scrollView
work. Am I reading dangling pointer when scrollView
is unsafe_unretained? Are there better solution to that situation?
Upvotes: 2
Views: 907
Reputation: 623
The issue here is by the time willMoveToSuperview
is called the scrollView
weak
pointer is already nil
(deallocated).
But it think scrollView not completely deallocated(memory not released) thats why when you use unsafe_unretained
reference to remove observer it works somehow. But it is a dangling pointer reference and you should not rely on that.
Upvotes: 1