Sal*_*rtz 5 cocoa-touch objective-c objective-c-blocks
我正在研究一些CoreAnimation的东西.带有几个视图控制器的导航控制器.并且视图控制器具有用于"小册子"的不同"页面"的UISCrollView.在每个页面上,可能会有一些动画在用户翻转到该页面时被触发.
我正在尝试这样的事情(对于一次性动画).
void (^animationBlock)() =
^{
static bool alreadyTriggered = NO;
if(alreadyTriggered)
return;
[CATransaction begin];
[CATransaction setCompletionBlock:
^{
alreadyTriggered = YES;
}];
// Do me some animations...
[CATransaction commit];
};
NSMutableDictionary* pageBlocks = [[NSMutableDictionary alloc] init];
[pageBlocks setObject:[animationBlock copy] forKey:<animation's name>];
[self.animationBlocks setObject:pageBlocks forKey:<some page number>];
[pageBlocks release];
[animationBlock release];
Run Code Online (Sandbox Code Playgroud)
"动画的名称"和"某些页码"是占位符以便解释(它们是任意的NSString文字).
触发这些动画的代码是:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
int pageNumber = floor(self.scrollView.contentOffset.x / self.scrollView.frame.size.width);
NSMutableDictionary* pageBLocks = [self.animationBlocks objectForKey:[NSString stringWithFormat:@"page%i",pageNumber]];
[CATransaction begin];
for(id key in pageBLocks)
((void (^)())[pageBLocks objectForKey:key])();
[CATransaction commit];
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切都那么好,只有如果我从导航控制器弹出小册子(也就是在小册子上调用dealloc)然后再将其推入,静态布尔仍然设置.
我的想法:
- 我保留了这块? 我不知道..我在将它(带有副本)添加到字典后调用release,并且小册子的dealloc方法调用字典上的release.
- 我在哪里保留静态bool的另一个副本? 当我在方法范围内将块声明为静态时,我的第一个bool被分配.很好地取决于Objective-C的激活记录方案,我没有考虑过.但假设是这样,当在popViewcOntroller上释放对象时,该副本就消失了.当字典被杀死时,应该在将字符串中的副本添加到字典时释放它的另一个副本吗?
我是否保留整个宣传册内容?我没有完全从Apple文档中获取它,但他们说如果我通过引用访问实例变量,我保留自己.我尝试从块内释放自我,一切都运行得很好......?
让块返回一个值,然后决定是否从字典中删除该块。
// ...
BOOL shouldRemove = block();
if (shouldRemove) {
[pageBlocks removeObjectForKey:key];
}
// ...
Run Code Online (Sandbox Code Playgroud)
让我们测试一下静态变量
@interface TestClass : NSObject
@end
@implementation TestClass
- (void(^)(void))block;
{
return [[^{
static BOOL staticBOOL = NO;
NSLog(@"%d", staticBOOL);
staticBOOL = YES;
} copy] autorelease];
}
@end
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
TestClass *test1 = [[TestClass alloc] init];
test1.block();
test1.block();
TestClass *test2 = [[TestClass alloc] init];
test2.block();
test2.block();
[p release];
}
Run Code Online (Sandbox Code Playgroud)
这输出
#=> 2012-04-23 00:43:38.501 Untitled[8380:707] 0
#=> 2012-04-23 00:43:38.503 Untitled[8380:707] 1
#=> 2012-04-23 00:43:38.503 Untitled[8380:707] 1
#=> 2012-04-23 00:43:38.504 Untitled[8380:707] 1
Run Code Online (Sandbox Code Playgroud)
我们如何解决这个问题呢?一旦像这样执行,我可能会从字典中删除该对象
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
{
NSInteger pageNumber = floor(self.scrollView.contentOffset.x / self.scrollView.frame.size.width);
NSMutableDictionary *pageBlocks = [self.animationBlocks objectForKey:[NSString stringWithFormat:@"page%i", pageNumber]];
[CATransaction begin];
for (id key in [pageBlocks copy]) {
void (^block)(void) = [pageBlocks objectForKey:key];
if (block) {
block();
}
[pageBlocks removeObjectForKey:key];
}
[CATransaction commit];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2787 次 |
| 最近记录: |