2012-11-26 27 views
1

我在塊內創建了一個NSObject。按下面的代碼:iOS NSObject在塊中初始化後爲零

__block NSObject *myObject; 

[self myMethod:^{ 
    myObject = [[NSObject alloc] init]; 
    .... 
}]; 

if(myObject == nil){ 
    NSLog(@"Why is my object nil?!"); 
} 

myMethod定義我有以下幾點:

backgroundQueue = dispatch_queue_create("backgroundqueue", NULL); 

      dispatch_async(backgroundQueue, 
          ^{ 

           dispatch_async(dispatch_get_main_queue(), 
               ^{ 
                if(block){ 
                 block();//Never called. 
                } 
               }); 

然而塊永遠不會被調用。

+0

希望這個答案幫助 - http://stackoverflow.com/questions/8878358/obj-c-block-variables – Jirapong

回答

3

這裏的問題是,你似乎永遠不會執行你實例化的塊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)[email protected]"Your object was created":@"Why is my object nil?"); 
    } 
} 

這將打印2012-11-26 05:00:58.519 Untitled 2[23467:707] Your object was created到控制檯。關鍵是塊不會自行執行。在上面的代碼中,儘管我們將塊設置爲類的ivar,但在我們的Foo上調用someMethod之前,我們不會執行它。

編輯:

你的問題的編輯指出,該塊未發送到主隊列異步分派塊的上下文中執行。如果這是一個命令行應用程序,那麼您必須在main的末尾調用dispatch_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)[email protected]"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)[email protected]"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(); 
} 
+0

對不起我們的一些代碼是有點類似。但我真的沒有複製你的。在我差不多完成我的工作之前,我沒有看到你的答案。在這裏,我的網絡非常緩慢。 – sunkehappy

+0

確實你是對的!請看看我所做的修改。對我的問題 –

0

你忘了打電話給你塊你myMethod。試試下面的代碼。

typedef void(^MyBlock)(); 

- (void)myMethod:(MyBlock)aBlock 
{ 
    aBlock(); 
}