简体   繁体   English

超出范围后销毁UIImageView对象

[英]Destroy UIImageView objects after they move out of bounds

In my application I have some images falling from above inside a UIView. 在我的应用程序中,我有一些图像从UIView上方掉落。 The UIImageView objects are created dynamically and made to move downwards. UIImageView对象是动态创建的,并可以向下移动。 My question is, do the objects destroy themselves after they move off below the screen area? 我的问题是,物体离开屏幕区域下方后是否会自毁? Or should I do it manually to improve performance? 还是应该手动执行以提高性能?

Once there are no more strong references to an object, it will be deallocated. 一旦不再有对某个对象的强引用,该对象将被释放。 The two references you probably need clear will be the variable pointer, and the superview's reference to it. 您可能需要清除的两个引用将是变量指针,以及超视图对其的引用。 So you'd need to do something like: 因此,您需要执行以下操作:

[imageView removeFromSuperView];
imageView = nil;

It's possible there are more as you did not provide any code (if for instance you have a pointer to the object in an array, you'd need to remove that too). 由于您未提供任何代码,因此可能还有更多的内容(例如,如果您有指向数组中对象的指针,则也需要将其删除)。

Removing from superview is all that's needed if you don't have any other pointers to the image view (in ARC). 如果您没有其他指向图像视图的指针(在ARC中),则只需从superview中删除。 The most performant pattern is to keep a pool of pointers to offscreen image views. 最有效的模式是保留指向屏幕外图像视图的指针池。 In pseudo code: 用伪代码:

// this assumes the number onscreen is relatively small, in the tens or low hundreds
// this works better when the number on screen is relatively constant (low variance)

// say the animation looks something like this:

- (void)makeAnImageFall:(UIImage *)image {

    CGRect startFrame = // probably some rect above the superview's bounds
    UIImageView *imageView = [self addImageViewWithImage:image frame:frame];  // see below
    [UIView animateWithDuration:1.0 animations:^{
        imageView.frame = // probably some rect below the superview's bounds
    } completion:^(BOOL finished) {
        [self removeImageView:imageView];  // see below
    }];
}

Then these methods do everything to handle the pool: 然后,这些方法会做所有事情来处理池:

- (UIImageView *)addImageViewWithImage:(UIImage *)image frame:(CGRect)frame {

    UIImageView *imageView;
    // assume you've declared and initialized imageViewPool as an NSMutableArray
    // or do that here:
    if (!self.imageViewPool) self.imageViewPool = [NSMutableArray array];

    if (self.imageViewPool.count) {
        imageView = [self.imageViewPool lastObject];
        [self.imageViewPool removeLastObject];
    } else {
        imageView = [[UIImageView alloc] init];
    }
    imageView.image = image;
    imageView.frame = frame;
    [self.view addSubview:imageView];
    return imageView;
}

- (void)removeImageView:(UIImageView *)imageView {
    imageView.image = nil;
    [self.imageViewPool addObject:imageView];
    [imageView removeFromSuperview];
}

The nice idea is that we avoid the relatively expensive churn of create-destroy of many image views. 好的主意是,我们避免了相对昂贵的创建多个图像视图的破坏。 Instead, we create them (lazily) when they're first needed. 相反,我们在第一次需要它们时(懒惰地)创建它们。 Once we hit the high water mark of image views, we don't ever allocate another. 一旦我们达到了图像视图的最高水准,就再也不会分配其他图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM