自定义UIView子视图的最佳实践强与弱

时间:2013-07-07 23:16:47

标签: ios objective-c memory-management

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

所以遇到2个问题。如果我将superview和子视图引用强大,那么视图就会泄漏。如果我让他们变弱,他们根本就不会出现。我做错了什么?

CustomUIView

@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

AnotherCustomUIView

@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

2 个答案:

答案 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因为它们的高级视图对它们有很强的引用。

所以,虽然我指出你的初级对象不应该对你的高级对象有强烈的引用(没有人会解除分配;这被称为保留周期并导致内存泄漏)可能是你的高级对象不应该对您的初级对象有强烈的引用,除非您希望它即使在视图层次结构中也不会出现。毕竟这些是观点;我想说创建你的初级对象,将它弹出到视图层次结构中,然后在弱属性中保存对它的引用,这样你只要存在它就可以访问它。然后,当您从视图层次结构中删除它时,您的引用会结束。

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

参考:Apple Docs, addSubview:

答案 1 :(得分:2)

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