2012-11-26 3 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로 설정했지만 someMethodFoo에 호출하기 전에는 블록을 실행하지 않습니다.

편집 :

질문에 대한 편집 블록이 메인 큐에 전송 비동기 파견 블록의 컨텍스트에서 실행되지 않은 상태. 명령 행 응용 프로그램 인 경우 main 끝에 dispatch_main()을 호출해야합니다. dispatch_get_main_queue()에 대해서는 man 페이지를 참조하십시오. 다음은이뿐만 아니라, 경쟁 조건과 관련된 문제를 설명하기 위해 전체 작업 명령 줄 응용 프로그램입니다 :

#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(); 
}