Objective-C块中的静态变量? [英] static variables inside Objective-C blocks?

查看:135
本文介绍了Objective-C块中的静态变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究一些CoreAnimation的东西。具有几个视图控制器的导航控制器。并且视图控制器具有用于小册子的不同页面的UISCrollViews。在每个页面上,可能有一些动画在用户翻页到该页面时触发。

I'm working on some CoreAnimation stuff. A navigation controller with a few view controllers. And the view controllers have UISCrollViews for different "pages" of a "brochure." On each page, there might be some animation that gets triggered when the user flips to that page.

我在尝试这样的动作(一次性动画)。

I was trying something like this (for one-shot animations).

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];

动画名称和一些页码是为了说明的占位符NSString文字)。

"animation's name" and "some page number" are placeholders for the sake of explanation (they are arbitrary NSString literals).

触发这些动画的代码是:

And the code that triggers these animations is:

- (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];
 }

到目前为止很好,只有如果我从导航控制器

So far so good, only that If I pop the brochure from the navigation controller (aka calls dealloc on the brochure) and then push it in again, the static bool is still set.

我的想法:

My thoughts:

- 我保留了阻止吗?
我不知道..我在添加它之后调用释放字典和小册子的dealloc方法调用字典上的释放。

- am I retaining the block? I don't know.. I'm calling release after adding it (with copy) to the dictionary and also the brochure's dealloc method calls release on the dictionary.

- 是否将静态bool的另一个副本保存在某处?
当我在方法范围内声明块为静态时,我的第一个bool被分配。很好地取决于我没有研究过的Objective-C的激活记录方案。但是假设这样,当在popViewcOntroller上释放对象时,该副本就消失了。当字典被杀死时,应该释放将其添加到字典中时从块上调用副本的另一个副本?

- am I keeping another copy of the static bool somewhere? My first bool is allocated when I declare the block as static within the scope of a method.. well depends on Objective-C's activation record scheme which I haven't looked into. But assuming so, that copy is gone when releasing the object on popViewcOntroller. And another copy of it from invoking copy on the block when adding it to the dictionary should be released when the dictionary is killed?

我保留整个小册子对象本身?我没有完全从苹果的文档,但他们说如果我访问一个实例变量通过引用我保留自我。我尝试从块中释放self,一切继续运行正常...

am I retaining the whole brochure object itself? I didn't completely get it from the Apple docs, but they say if I access an instance variable by reference I retain self. I tried releasing self from inside the block and everything keeps running just fine...?

推荐答案

使块返回一个值,然后决定是否从字典中删除该块。

Make the block return a value and then decide whether or not to remove the block from the dictionary.

// ...
    BOOL shouldRemove = block();

    if (shouldRemove) {
        [pageBlocks removeObjectForKey:key];
    }
// ...





$ b b

让我们测试静态变量


Let's test the static variable

@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];
}

输出

#=> 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

问题?我可能会删除对象从字典一旦它像这样执行

How do we solve the problem? I would probably remove the object from the dictionary once it had been executed like this

- (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];
}

这篇关于Objective-C块中的静态变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆