这里的问题是您似乎从未执行过您在其中实例化的块myObject
。为了说明,运行这个小程序:
#import <Foundation/Foundation.h>
typedef void(^MyTestBlock)(void);
@interface Foo:NSObject
- (id)initWithBlock:(MyTestBlock)aBlock;
- (void)someMethod;
@end
@implementation Foo {
MyTestBlock _block;
}
- (id)initWithBlock:(MyTestBlock)aBlock {
self = [super init];
if( !self ) { return nil; }
_block = aBlock;
return self;
}
- (void)someMethod {
_block();
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
__block NSObject *myObject;
Foo *myFoo = [[Foo alloc] initWithBlock:^{
myObject = [[NSObject alloc] init];
}];
[myFoo someMethod];
NSLog((myObject)?@"Your object was created":@"Why is my object nil?");
}
}
这将打印2012-11-26 05:00:58.519 Untitled 2[23467:707] Your object was created
到控制台。关键是块不会自己执行。someMethod
在上面的代码中,虽然我们将块设置为类的 ivar,但在调用Foo
.
编辑:
对您的问题的编辑指出,该块未在发送到主队列的异步调度块的上下文中执行。如果这是一个命令行应用程序,那么您必须dispatch_main()
在main
. 请参阅man
页面dispatch_get_main_queue()
。这是一个完整的命令行应用程序来说明这一点,以及与竞争条件相关的问题:
#import <Foundation/Foundation.h>
typedef void(^MyTestBlock)(void);
@interface Foo:NSObject
- (id)initWithBlock:(MyTestBlock)aBlock;
- (void)someMethod;
@end
@implementation Foo {
MyTestBlock _block;
}
- (id)initWithBlock:(MyTestBlock)aBlock {
self = [super init];
if( !self ) { return nil; }
_block = aBlock;
return self;
}
- (void)someMethod {
dispatch_queue_t backgroundQueue = dispatch_queue_create("backgroundqueue", NULL);
dispatch_async(backgroundQueue, ^{
dispatch_queue_t innerQueue = dispatch_get_main_queue();
dispatch_async(innerQueue, ^{
if( _block){
NSLog(@"Will call block.");
_block();
}
});
});
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
__block NSObject *myObject;
Foo *myFoo = [[Foo alloc] initWithBlock:^{
myObject = [[NSObject alloc] init];
}];
[myFoo someMethod];
// this log statement should show that myObject is nil because it will (probably)
// be executed before your block.
NSLog((myObject)?@"Your object was created":@"Why is my object nil?");
// wait a little bit to resolve race condition (just for illustrative purposes)
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.4f * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog((myObject)?@"Your object was created":@"Why is my object nil?");
});
}
// this isn't a Cocoa app, so must call dispatch_main() at end of main
dispatch_main();
}