如何命名代码块并以不同的方法调用它?

时间:2012-03-30 08:05:50

标签: objective-c ipad xcode4 objective-c-blocks

我使用Grand Central Dispatch方法在队列中执行我的应用程序。我决定在该队列的计算中按钮的帧。我希望我的应用程序重新绘制其scren并在旋转后计算新帧。这是我做的一些伪代码解释:

 CGFloat a=123, b=24;
     dispatch_async(drawingQue, ^{
        //needed loops to get the total button count-how many ones will be drawn et..
        for(int x=0;x<someCount<x++){
           for(int y=0;y<anotherCount;y++){

        //needed frame&name ect assingments

        button.frame= CGRectMake(x+y, x-y, a, b);
        [button setTitle:@"abc"];}}
        };

这里我想要的是,如何给这个块命名并在

中重复使用它
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
} 

委托方法?例如,如果旋转是横向的,我想使用a=234而不是123 ..请帮助。提前谢谢..

3 个答案:

答案 0 :(得分:6)

声明块类型的实例变量,并使用Block_copy来保留块:

@interface My {
    void (^myBlock)(void);
}
@end

myBlock = Block_copy(^{
    ...block code...
});

// later call it
myBlock();

// don't forget to release it in dealloc

在将块存储在其文字(^{...})范围之外之前复制这一点非常重要,因为原始块存储在堆栈中并在范围退出时死亡

答案 1 :(得分:1)

只需制作一个@property块,存储它,然后再使用它:

typedef void (^MyBlock)(CGFloat, CGFloat);
...
@property(readwrite, copy) MyBlock buttonFramesBlock;
...
@synthesize buttonFramesBlock;
...
self.buttonFramesBlock = ^(CGFloat a, CGFloat b){
    //needed loops to get the total button count-how many ones will be drawn et..
    for(int x=0;x<someCount<x++){
       for(int y=0;y<anotherCount;y++){

    //needed frame&name ect assingments

    button.frame= CGRectMake(x+y, x-y, a, b);
    [button setTitle:@"abc"];}}
};
...
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    dispatch_async(drawingQue, ^{
        self.buttonFramesBlock(234,someOtherInt);
    });
} 

答案 2 :(得分:1)

首先,永远不要在主线程之外更改UI。因此,您应该将代码修改为:

dispatch_async(drawingQue, ^{
    // ...

    dispatch_async(dispatch_get_main_queue(), ^{
        button.frame= CGRectMake(x+y, x-y, a, b);
        [button setTitle:@"abc"];
    });
});

其次,永远不要在方法shouldAutorotateToInterfaceOrientation内更改UI。在该方法中您需要做的就是返回视图是否应该旋转。例如,在某些情况下,如果您有视图控制器层次结构,即使您在YES中返回shouldAutorotateToInterfaceOrientation,该视图也可能无法轮换。

所以,你应该在方法中调用你的代码:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

这可以通过多种方式实现。最简单的(也是我推荐的)是使用标准的Objective-C方法:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) { // landscape
        [self rotateButtonWithA:234 b:24];
    } else { // portrait
        [self rotateButtonWithA:123 b:24];
    }

}

- (void)rotateButtonWithA:(CGFloat)a b:(CGFloat)b
{
    dispatch_async(drawingQue, ^{
        // ...

        dispatch_async(dispatch_get_main_queue(), ^{
            button.frame= CGRectMake(x+y, x-y, a, b);
            [button setTitle:@"abc"];
        });
    });
}

你真的不需要从多个地方调用块本身。但如果你仍然想这样做,这里有很多答案可以告诉你如何做到这一点。