IOS 가 잠 금 으로 UI 가 죽 는 예 를 실현 합 니 다.

2766 단어 IOSUI 가사
IOS 가 잠 금 으로 UI 가 죽 는 예 를 실현 합 니 다.
현상.
앱 이 시 작 된 지 일정 시간 이 지나 면(약 30 분 정도)앱 인터페이스 에서'동사'현상 이 자주 발견 된다.동시 배경 출력:

[CocoaGoPush]WorkThreadProc end
이때 앱 은'가사'상 태 를 보 여 주 며 화면 어디 에 도 반응 하지 않 았 고,아이 폰 은 화면 을 열 고 끄 는 것 외 에는 아무런 응답 이 없 었 다(홈 버튼 을 누 르 는 것 포함).물론 잠 금 을 풀 수도 없 었 다(단 다시 시작 할 수도 있 었 다).Xcode 로 프로그램 을 종료 하면 아이 폰 이 다시 정상화 된다.
주:앱 은 코코아 고 푸 시 프레임 워 크 를 사 용 했 습 니 다.
발견 하 다.
프로그램 메 인 스 레 드 에서 사 순환 이 생 겨 UI 가 반응 하지 않 는 줄 알 았 다.그러나 Debug 도구 모음 에 있 는 Pause 단 추 를 누 르 고 현재 실행 중인 스 레 드 를 보 여 주 었 을 때 문제 가 그렇지 않 고 잠 금 에 사용 되 는 것 을 발견 하 였 습 니 다.디 버 깅 이 중 단 된 후,정지점 은 이 문장 에 멈 추 었 다.

app.gopushLock.lock()// MARK: yhy removed          
app.gopushLock 은 NSRecursiveLock 대상 입 니 다.

let gopushLock = NSRecursiveLock()
NSRecursiveLock 은 재 귀적 자물쇠 로 같은 스 레 드 에서 여러 번 자 물 쇠 를 요청 할 때 잠 금 이 발생 하지 않 습 니 다.그러나 프로그래머 가 두 스 레 드 에서 재 귀 자 물 쇠 를 잘못 사용 하면'잠 금'이 나타 나 기 쉽다.두 스 레 드 가 같은 자 물 쇠 를 동시에 잠 그 는 동시에 이 자물쇠 가 잠 겨 있 고 서로 가 잠 금 을 풀 기 를 기다 리 는 것 을 발견 하면 두 스 레 드 가 실행 되 지 못 한다.특히 한 쪽 은 메 인 스 레 드 의 경우 메 인 스 레 드 가 막 히 고 UI 는 가사 상 태 를 보인다.이 예 에서 gopush 가 있 는 스 레 드 도 멈 추고 gopush 메 시 지 를 계속 듣 지 않 으 며 심장 박동 을 유지 하 는 것 으로 나 타 났 다.
코드 를 검사 한 결과 코드 가 다른 곳 에서 이 귀속 자 물 쇠 를 사 용 했 습 니 다.

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler:{
      (response, data, error) -> Void in

      if (error != nil) {
        app.gopushLock.lock()
        app.isGoPushFetchingMessage = false
        app.gopushLock.unlock()
        println("-----------GoPush Message Guard fail to fetch offline message. err = \(error.localizedDescription)-----------")
        ...
 })

NSURLConection.sendAysnchronous Request 방법 으로 새로운 스 레 드 에 요청 을 보 냈 기 때문에 app.gopushLock.lock()은 실제 하위 스 레 드 에서 호출 되 었 습 니 다.다른 곳(첫 번 째 코드)은 메 인 스 레 드 에서 호출 되 었 기 때문에'경쟁'을 초래 했다.
해결 하 다.
방법 1
메 인 스 레 드 의 재 귀 잠 금 호출 설명 을 하위 스 레 드 의 재 귀 잠 금 호출 만 남 겨 두 십시오.
방법 2
메 인 스 레 드 에서 서로 다른 자 물 쇠 를 사용 합 니 다.예 를 들 어 NSLock 을 메 인 스 레 드 에 사용 하 는 것 을 다시 정의 하고 서브 스 레 드 의 gopushLock 과 구별 합 니 다.
방법
gopushLock 의 종 류 를 NSRecursiveLock 에서 NSLock 으로 변경 합 니 다.말 그대로 재 귀 자 물 쇠 는 순환 이나 재 귀 에서 동기 화 되 어야 하 는 코드 에 만 사용 되 지만 두 스 레 드 가 동시에 잠 금 코드 에 접근 하 는 것 을 피 할 수 없다.그러나 NSLock 은 반대로 두 스 레 드 가 잠 긴 코드 에 동시에 접근 하 는 것 을 피 할 수 있 지만 같은 스 레 드 에서 동기 코드 에 잠 금 을 추가 하 는 상황 을 피 할 수 없습니다.두 번 째 단계 에서 재 귀 자 물 쇠 를 호출 하 는 상황 을 검사 한 결과 재 귀 자 물 쇠 를 사용 할 필요 가 전혀 없 음 을 발견 했다.코드 에 재 귀 도 순환 도 없 기 때문이다.따라서 NSRecursiveLock 대신 gopushLock 을 NSRecursiveLock 으로 안심 하고 수정 할 수 있 습 니 다.
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기