所以我正在编写一个继承自UIView的自定义类。我有一堆子视图,我添加。
所以遇到2个问题。如果我将superview和子视图引用强大,那么视图就会泄漏。如果我让他们变弱,他们根本就不会出现。我做错了什么?
@interface CustomUIView : UIView
@property(nonatomic, strong) AnotherCustomUIView *mySubView;
@end
@implementation CustomUIView {
- (void)initCommon {
self.mySubView = [self createSubView]
}
- (AnotherCustomUIView *) createSubView {
return [[AnotherCustomUIView alloc] init:self];
}
@end
@interface AnotherCustomUIView : UIScrollView
@property (nonatomic, strong) CustomUIView *ownerView;
@end
@implementation AnotherCustomUIView
- (id)init:(CustomUIView *) ownerView {
self = [super init];
if (self) {
self.ownerView = ownerView;
self.delegate = self;
}
return self;
}
@end
答案 0 :(得分:10)
根据您的代码,我认为您在强引用和弱引用之间存在混淆,以及它们与内存管理的关系。
首先,这是对强弱对象的一个很好的描述:https://stackoverflow.com/a/11013715/700471
在您的特定情况下,ownerView
上的AnotherCustomUIView
属性应该很弱,因为它指向一个高级对象。代表参考也很薄弱,我不知道设置self.delegate = self;
会产生任何负面影响。
编辑:
为了澄清,将视图添加为另一个视图的子视图会创建一个强引用。一旦您的视图是视图层次结构的一部分,就不需要进一步强引用。所以你有这个代码:
[mySeniorView addSubView:myJuniorView]; // myJuniorView will not be released.
mySeniorView.juniorView = myJuniorView; // This shouldn't be a strong reference.
在上面的代码中,如果mySeniorView.juniorView
是强引用,则它是多余的。如果从视图层次结构中删除myJuniorView
,则不会释放它,因为您仍然有另一个强引用。如果.juniorView
是弱引用,则从视图层次结构中删除myJuniorView
将导致其取消分配并将.juniorView
设置为nil
。
这就是为什么,例如,所有IBOutlet属性都应该是弱的;因为你连接它们的xib中的东西是视图层次结构的一部分,所以不会dealloc因为它们的高级视图对它们有很强的引用。
所以,虽然我指出你的初级对象不应该对你的高级对象有强烈的引用(没有人会解除分配;这被称为保留周期并导致内存泄漏)可能是你的高级对象不应该对您的初级对象有强烈的引用,除非您希望它即使在视图层次结构中也不会出现。毕竟这些是观点;我想说创建你的初级对象,将它弹出到视图层次结构中,然后在弱属性中保存对它的引用,这样你只要存在它就可以访问它。然后,当您从视图层次结构中删除它时,您的引用会结束。
无论如何,希望有所帮助。
答案 1 :(得分:2)
几乎总是对父母的引用应该是弱的。这是典型的指挥链。父母创建并“拥有”孩子,孩子只观察其父母。你希望孩子存在依赖于父母,而不是相反。