2011-01-10 3 views
3

나는 ObjectiveResource (iOS-> Rails bridge)으로 몇 가지 테스트를 해왔다. 상황은 정상적으로 작동하지만 라이브러리는 동기식 (또는 그렇지 않을 수도 있지만 the mailing list that supports it is a mess)입니다.performSelectorInBackground를 사용할 때의 위험성은 무엇입니까?

것은 내가 함정이 그냥 잘 작동하는 것 같다 작은 테스트에서 ... performSelectorInBackground에 대한 모든 호출을 실행하기 위해 무엇인지 궁금하네요,하지만 그건 잘못된 여러 가지의 경우입니다.

내가 알아 차린 유일한주의 사항은 performSelectorInBackground에서 호출 한 메서드에서 자동 복구 풀을 만들어야한다는 것입니다. 그러면 이면서 release이 아닌 전화 만해야합니다.

답변

8

performSelectorInBackground:은 백그라운드에서 스레드를 사용하며 스레드가있는 큰 점은 하나 이상의 코드가 접촉 한 코드가 경쟁 조건 및 기타 미세한 지형 버그. 이것은 분명히 화면으로의 드로잉이 메인 쓰레드 외부에서 벗어나는 것을 의미합니다. 그러나 스레드 세이프가 아닌 다른 많은 라이브러리가 있으며 이들을 사용하는 코드도 오염되어 있습니다.

기본적으로 스레드 안전은 의도적으로 코드에 입력해야하거나 그렇지 않은 것일 수 있습니다. ObjectiveResource는 그것에 대한 어떤 주장도하지 않으므로 이미 긴장 할 것입니다. 출처를 보면, 주로 스레드 안전 IIRC 인 Foundation URL 로딩 기계를 사용하는 것 같습니다. 그러나 ObjectiveResource 코드 자체는 아닙니다. 한눈에, 모든 클래스 메서드는 정적 변수를 사용합니다. 즉, 변수를 사용하는 코드로 두 번 이상 performSelectorInBackground:을 입력하면 모두 경쟁 조건이 적용됩니다.

Github의 1.1 분기에는 ConnectionManager 클래스를 통한 비동기 지원이 명시되어 있습니다. 아마도 이것을 사용하는 것이 더 나을 것입니다 (이것은 본질적으로 유지 보수되지 않은 코드이므로주의해야합니다).

+0

그 분석에 대해 많은 감사를드립니다, @ 척. ObjResource 문제의 근원 중 하나는 상속이 아닌 모든 카테고리를 사용한다는 것입니다. 상속을 해제하는 것이 좋지만, 카테고리에 변수를 넣을 수 없기 때문에 Obj-C에서 정말 제한적입니다. 어쨌든, 나는 이것을 너무 많이 만들 수 있다고 생각한다. "비즈니스"앱의 경우 블로킹, 동기식 콜은 아마 괜찮을 것이다. –

+0

백그라운드 스레드에서 UIView 조각을 만드는 것이 안전합니까? 내가 거기에있는 동안 보이는 뷰에 첨부하지 않는 한? –

8

실제로 문제가 있습니까? 또는 당신은 그 (것)들을 다만 예기하고 있는가?

동일한 백그라운드 스레드에서 UI 요소를 업데이트하려고 시도하지 않는 한 백그라운드 스레드에서 실행해도 문제가 발생하지 않습니다. UI 관련 작업을 주 스레드로 전달해야합니다. 예를 들어 (의사) : 당신이 배경 스레드에서 인스턴스 변수의 값을 변경하는 경우, 그것은 당신이 (다른 스레드를 방지하기 위해 self에 동기화하는 것이 중요하다는

- (void)viewWillAppear:(BOOL)animated { 
    [self performSelectorInBackground:@selector(refreshTableView)]; 
    [super viewWillAppear:animated]; 
} 

- (void)refreshTableView { 
    // Where _listOfObjects is used to populate your UITableView 
    @synchronized(self) { 
     self._listOfObjects = [MyDataType findAllRemote]; 
    } 
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; 
} 

도 (위에서) 주 스레드와 마찬가지로) 업데이트 또는 설정 중에 _listOfObjects 배열의 개체에 액세스하지 못하게합니다. (또는 불완전한 객체를 가져올 수 있습니다.)

_listOfObjects 속성을 atomic으로 선언하면 걱정하지 않아도됩니다. (의견 환영합니다.) 동기화 된 블록 이지만 속성 값을 재 할당하는 대신 하나의 영구 인스턴스를 변경하려는 경우 @property 선언에 관계없이 동기화 된 블록이 필요합니다. (예 : 정적 NSMutableArray에서 객체 추가/제거)

+0

내가 문제를 예상하고 있다고 말할 수 있습니다. 지금 레일즈 서버를 종료하면 ObjectiveResource가 즉시 잘못된 답을 반환합니다 (오류를 반환하는 대신 레코드 수가 0). 나는 당신이 객체 자체를 조정하지 않는다면 원자가 충분해야한다는 것에 동의한다. 아, 그리고 배경 스레드를위한 새로운 autorelease pool이 필요합니다. –

+0

좋은 지적 - 추가 자동 릴리스 풀에 대해 완전히 잊었습니다. –

+0

오류에 대한 나의 의견이 잘못되었습니다. 오류를 반환하는 메커니즘이 있습니다. –

관련 문제