9

所以我正在编写一个继承自 UIView 的自定义类。我有一堆子视图,我添加了。

所以遇到2个问题。如果我使超级视图和子视图引用强,则视图正在泄漏。如果我让他们变得虚弱,他们根本就不会出现。我究竟做错了什么?

自定义UIView

@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

另一个CustomUIView

@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
4

2 回答 2

10

根据您的代码,我认为您在强引用和弱引用之间存在混淆,以及它们与内存管理的关系。

首先,这里是强与弱的一个很好的描述:https ://stackoverflow.com/a/11013715/700471

在您的特定情况下,ownerView属性 onAnotherCustomUIView应该很弱,因为它指向高级对象。委托引用也很弱,我不知道设置self.delegate = self;有什么负面影响。

编辑:

澄清一下,添加一个视图作为另一个视图的子视图会创建对它的引用。一旦您的视图是视图层次结构的一部分,就不需要进一步的强引用。所以你有这个代码:

[mySeniorView addSubView:myJuniorView]; // myJuniorView will not be released.
mySeniorView.juniorView = myJuniorView; // This shouldn't be a strong reference.

在上面的代码中, ifmySeniorView.juniorView是一个强引用,它是多余的。如果您myJuniorView从视图层次结构中删除它不会被释放,因为您仍然有另一个强引用它。如果.juniorView是弱引用,myJuniorView则从视图层次结构中删除将导致它解除分配并设置.juniorViewnil.

这就是为什么,例如,您的所有 IBOutlet 属性都应该是弱的;因为您将它们连接到的 xib 中的东西是视图层次结构的一部分,因此不会解除分配,因为它们的高级视图对它们有很强的引用。

因此,虽然我指出您的初级对象不应该对您的高级对象有强引用(两者都不会释放;这称为保留周期并导致内存泄漏),但您的高级对象可能不应该对高级对象有强引用你的初中生,除非你想让它在视图层次结构中不存在。毕竟,这些都是观点;我会说创建您的初级对象,将其弹出到视图层次结构中,然后在弱属性中保存对它的引用,这样只要它存在,您就可以访问它。然后,当您将其从视图层次结构中删除时,您的引用将无效。

无论如何,希望这会有所帮助。

参考:Apple Docs,addSubview:

于 2013-07-07T23:51:10.097 回答
2

几乎总是对父级的引用应该是弱的。这是典型的指挥链。父级创建并“拥有”子级,而子级仅观察其父级。您希望孩子在存在上依赖父母,而不是相反。

于 2016-02-12T00:16:33.823 回答