4

何时复制块?该文档说,块“在执行从定义它们的范围返回时被删除。这意味着你不能直接从函数中返回它们。如果块只能在其定义范围仍在调用堆栈上时使用,它们不会像实际那样有用”

因此,这是我尝试过的代码,希望在 viewDidLoad 中执行完成后删除该块。

MyReaderController.h

@interface MyReaderController : UIViewController
{
    myBlockVar aBlockVar;
}
-(myBlockVar) getABlock;
@end

MyReaderController.m

@implementation MyReaderController
- (void)viewDidLoad
{
    [super viewDidLoad];
    aBlockVar=[self getABlock];
    NSLog(@"Block Result = %f",aBlockVar(1));
}
-(void) viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    NSLog(@"Block Exists even after the execution completes=%@ %f",aBlockVar,aBlockVar(5));
}

-(myBlockVar) getABlock{
    return ^(int var){return 4.0f;};
}

@end

那么,此代码是否需要将 viewDidLoad 更改为如下所示,如果不需要,那么我应该何时使用它。

- (void) viewDidLoad{
    [super viewDidLoad];
    aBlockVar=Block_copy([self getABlock]);
    NSLog(@"Block Result = %f",aBlockVar(1));
}

第2部分

后来我尝试使用以下代码,希望现在它会在 viewDidDisappear 中将 aBlockVar 作为 nil obj 返回。

- (void)viewDidLoad
{
    [super viewDidLoad];
    Blocker *blocker=[[Blocker alloc] init];
    myBlockVar myVar=[blocker getABlock];
    aBlockVar=myVar;
    NSLog(@"Block Result = %f",aBlockVar(1));
    blocker=nil;
    myVar=nil;
}

拦截器.m

#import "Blocker.h"

@implementation Blocker

-(myBlockVar) getABlock{
    return ^(int var){return 4.0f;};
}
@end
4

4 回答 4

5

你在用ARC吗?如果是这样,您不需要使用Block_copyor Block_release

如果是,那么您对修改后的代码是正确的,因为Block_copy将其从堆栈中取出并放入有效保留计数为 1 的堆中。您还需要Block_release在最终完成块时在适当的地方调用,使其平衡副本,有效地将保留计数恢复为 0。

于 2013-03-03T09:51:59.537 回答
2

现有答案的附录:

即使您使用 ARC,在某些情况下您仍然需要Block_copy. 例如,从 an 中提取一个块参数NSInvocation并在函数返回后使用它。

- (void)interceptInvocation:(NSInvocation *)call {
    BlockType block;
    [call getArgument:&block atIndex:2];  // ARC cannot see this happen
    block = (__bridge BlockType)Block_copy((__bridge void *)block);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        block();
    });
}

如果没有副本,块将在运行时被释放。似乎Block_release不需要匹配,因为当我添加一个时,由于版本太多而崩溃。

于 2014-04-25T08:26:56.213 回答
2

利用@property (nonatomic, copy) (int)(^myBlock)(void);

让系统为你做好内存管理!

初始化:

self.myBlock = ^int(void){
    return 4.0;
};

如果你想在某处摧毁你的街区self.myBlock = NULL;

于 2013-03-03T10:20:02.983 回答
1

有弧从不,没有弧:


: 当你有一个 STACK 块并希望将其保留为 HEAP 块时(例如,当你在函数中有一个块并希望它在退出函数后仍然存在!)

然后你需要block_copy它。


你也需要像 NSString 一样保留/释放它(使用 block_copy/block_release)

于 2013-03-03T10:48:02.800 回答