我做了一个小型的“加载器”,我可以在需要时粘贴在UI上。很像UISpinnerView。
它有一些逻辑(我简化了这个帖子的块中的代码),需要递归调用它。我是这样做的:
- (void) blink {
tick++;
if (tick > kNumberOfLights)
tick = 0;
UIView *lightOne = [self viewWithTag:kLightStartIndex];
UIView *lightTwo = [self viewWithTag:kLightStartIndex+1];
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
animations:^{
if (tick == 0) {
[lightOne setAlpha:kLightOn];
[lightTwo setAlpha:kLightOff];
} else if (tick == 1) {
[lightOne setAlpha:kLightOff];
[lightTwo setAlpha:kLightOn];
}
}
completion:^(BOOL finished){
[self blink];
}];
}
将视图添加到超级视图时,将调用方法[self blink]
。
Loader类中没有保留任何对象,因此当我在超级视图中删除它时 它被释放了。问题是如果在我释放视图时动画块正在运行,则完成块将调用一个解除分配的对象并导致错误:
(20380,0xa0a29540)malloc: * mmap(size = 2097152)失败(错误 代码= 12) * 错误:无法分配区域
在控制台和错误中:
__ [LoaderClass blink] _block_invoke_2
在Debug Navigator中。
如何从超级视图中删除视图时,如何确保正确拆除视图?
答案 0 :(得分:1)
覆盖释放通常是一个坏主意,但这种情况可能是规则的例外。
实例变量:
BOOL isBlinking;
BOOL releaseWhenDoneAnimating;
初始化isBlinking = NO和releaseWhenDoneAnimating = NO。
- (void)release
{
if(!isBlinking) {
[super release];
return;
}
releaseWhenDoneAnimating = YES;
}
- (void) blink {
isBlinking = YES;
if(releaseWhenDoneAnimating) {
[super release];
return;
}
tick++;
if (tick > kNumberOfLights)
tick = 0;
UIView *lightOne = [self viewWithTag:kLightStartIndex];
UIView *lightTwo = [self viewWithTag:kLightStartIndex+1];
[UIView animateWithDuration:0.5
delay: 0.0
options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
animations:^{
if (tick == 0) {
[lightOne setAlpha:kLightOn];
[lightTwo setAlpha:kLightOff];
} else if (tick == 1) {
[lightOne setAlpha:kLightOff];
[lightTwo setAlpha:kLightOn];
}
}
completion:^(BOOL finished){
[self blink];
}];
}