2011-12-19 5 views
1

dict 변수를 초기화하려고하는데 왜 한 방향이 작동하는지 이해하지 못하고 다른 방향은 작동하지 않습니다.블록 내에서 객체 초기화

모든 경우에 문제가 없으며 나중에 dict를 사용할 수 있습니다.
경우 2에서 곧 출시 될 것입니다 (좀비가됩니다) 나중에 (블록 외부에서) 사용하려고하면 프로그램이 중단됩니다.

다음은 ios 용으로 작성된 클래스입니다 (C++와 objective-c가 섞여 있음).
블록 내에서 나는 두 가지 다른 방법으로 변수 사전을 초기화하려고했습니다.

class Data 
{ 
public: 
    NSMutableDictionary *dict; 

    void DoSomeStuff() 
    { 
    [NSSomeFrameworkTool doSomeStuffWithCompletionHandler:^(NSError *err) { 
     // case 1 - OK 
     dict = [[NSMutableDictionary alloc] initWithDictionary:[NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"]]; 

     // case 2 - will crash later if i try to use dict 
     dict = [NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"]; }]; 
    } 
} 

이 클래스에는 DoSomeStuff() 메소드에서 초기화되는 클래스 변수 dict가 있습니다.
이 메서드는 블록을 콜백으로 사용하여 일부 작업이 완료되었음을 알리는 ios 프레임 워크의 메서드를 호출합니다.

저는 왜 케이스 1과 케이스 2가 다른지 궁금합니다. 블록 외부에서 참조를 사용하는 것은 금지되어 있습니다.이 블록 내부에서 초기화되었습니다.
case2에 표시된 것과 같은 방식으로 어떤 문제가 있습니까?

+0

실제 충돌의 원인은 무엇입니까? –

+0

안녕하세요. 그 줄은 없어. 내 말은, 블록 밖에서 dict를 나중에 사용하려고 할 때입니다. 예를 들어, 다른 방법으로 : DoSomeStuff2() {[dict count]; }. 그리고 그것은 충돌 할 것입니다 – majakthecoder

+0

ARC를 사용하고 있습니까? –

답변

2

첫 번째 경우에는 딕트를 해제하지 않고 두 번째 경우에는 자동 수거되어 있으므로 보유해야합니다.

dict = [[NSKeyedUnarchiver unarchiveObjectWithFile:@"dict.dat"] retain]; 
+0

예! 덕분에, 고마워. 이 객체는 블록의 beucase로 릴리즈되었거나 항상 어떤 스코프 내부에서 해제 되었습니까? – majakthecoder

2

여기서 블록 변수를 사용할 수 있다고 생각합니다.

__block NSMutableDictionary *dict; 

변수는 블록 내부에서 불변입니다. 그것들은 상수 카피이며, "블록 생성"시점의 변수 스냅 샷이므로 블록 내에서 수정할 수 없습니다. 블록 변수는 변수를 '스택'에서 '힙'으로 이동시켜 상태를 변경할 수있게합니다. 나는 블록에 대한 전문가는 아니지만, 그들이 목표 c에 상대적으로 새롭다는 것을 알고있다. 그러나 당신이 배우기 위하여 google 주위에 몇몇 좋은 기사가있다.

http://pragmaticstudio.com/blog/2010/7/28/ios4-blocks-1