iOS 는 노트북 키보드,정적 라 이브 러 리,애니메이션,Crash 포 지 셔 닝 을 개발 합 니 다.

9271 단어 ios건반crash
머리말
본 고 는 주로 개발 과정 에서 겪 은 문제 와 관련 된 사 고 를 공유 했다.필요 한 친구 들 에 게 참고 학습 을 공유 해 드 리 겠 습 니 다.다음 말 은 더 이상 하지 않 겠 습 니 다.상세 한 소 개 를 해 보 겠 습 니 다.
iOS 11 키보드 문제
기능 배경:
키 보드 를 꺼 낼 때 입력 상자 가 있 으 면 입력 상자 의 위치 가 키보드 크기 에 따라 바 뀌 어야 합 니 다.
질문 설명:
키 보드 를 빠르게 전환 하면 입력 상자 의 위치 가 키보드 에 붙 지 않 고 나타 나 기 쉽다.다음 과 같다.(약서 키 보드 를 예 로 들 면)

관련 실현:
입력 상자 감청 시스템 의 UIKeyboard WillShowNotification 과 UIKeyboard WillHideNotification 이 벤트 는 리 셋 과정 에서 UIKeyboard FrameEndUserInfoKey 로 키보드 의 frame 을 가 져 오고 입력 상자 의 위 치 를 동적 으로 조정 합 니 다.
질문 위치:
이 문 제 는 키 보드 를 부 른 후 키 보드 를 자주 바 꿀 수 있다.
Log 를 추가 하여 디 버 깅 을 하면 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.

/*
226          ;
292           ;
271 emoji     ;
*/
UIKeyboardWillShowNotification : {{0, 510}, {414, 226}}
UIKeyboardWillShowNotification : {{0, 444}, {414, 292}}
UIKeyboardWillShowNotification : {{0, 510}, {414, 226}}
UIKeyboardWillShowNotification : {{0, 444}, {414, 292}}
UIKeyboardWillShowNotification : {{0, 465}, {414, 271}}
UIKeyboardWillShowNotification : {{0, 510}, {414, 226}}
UIKeyboardWillShowNotification : {{0, 444}, {414, 292}}
실제 조작 에 서 는 키보드 가 292 높이 의 소 개 키보드 에서 271 의 emoji 키보드 로 바 뀌 었 을 때 리 셋 을 촉발 하지 못 해 실제 키보드 높이 에 292-271 의 오차(21pt)가 발생 하기 도 한다.
정상 적 인 애플 은 키 보드 를 바 꿀 때마다 리 셋 을 해 야 하지만 이모 티 콘 키 보드 를 바 꿀 때 가끔 리 셋 을 하지 않 는 다.
문제 복구:
입력 상자 의 높이 를 높이 고 위의 그림 왼쪽 빨간색 상자 부분의 높이 를 증가 합 니 다.
키보드 와 정렬 할 때 빨 간 상자 의 높이 를 아래로 계산한다.
첨부:
iOS 11 에는 또 다른 키보드 가 이상 하 게 나 타 났 다.앱 에서 키 보드 를 호출 하고 앱 을 배경 으로 자 르 며 시스템 데스크 톱 에서 시스템 검색 키 보드 를 내 려 가면 앱 안의 키 보드 를 접 을 수 있다.
정적 라 이브 러 리 관련
기능 배경:
프로젝트 에 일부 기능 이 존재 하 므 로 정적 라 이브 러 리 통합 방식 으로 접속 해 야 합 니 다.
질문 설명:
온라인 에서 실행 하 는 과정 에서 일부 Crash 가 정적 라 이브 러 리 에서 나 온 것 을 발 견 했 지만 Crash 로그 에 서 는 정적 라 이브 러 리 에 Crash 가 나타 나 는 구체 적 인 코드 줄 수 를 찾 을 수 없습니다.
다음 과 같이 testNull 의 Thread 0 에서 Crash 가 발생 하지만 함수 관련 정보 가 없습니다.

Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 testNull       0x000000010494aacc 0x104944000 + 27340
1 testNull       0x000000010494aac8 0x104944000 + 27336
2 testNull       0x000000010494a6b0 0x104944000 + 26288
3 UIKit        0x000000018cec4efc -[UIViewController loadViewIfRequired] + 1040
4 UIKit        0x000000018cec4ad4 -[UIViewController view] + 28
5 UIKit        0x000000018cecb6a0 -[UIWindow addRootViewControllerViewIfPossible] + 136
6 UIKit        0x000000018cec890c -[UIWindow _setHidden:forced:] + 272
7 UIKit        0x000000018cf379ec -[UIWindow makeKeyAndVisible] + 48
관련 실현:
정적 라 이브 러 리 는 별도의 프로젝트 가 있 습 니 다.시 뮬 레이 터 와 실제 컴퓨터 두 개의 프레임 워 크 를 포장 한 다음 하나의 프레임 워 크 로 합 쳐 프로젝트 의 프로젝트 에 넣 습 니 다.
질문 위치:
Crash 로그 에 있 는 정 보 를 기호 화 할 수 없습니다.그 이 유 는 Crash 정 보 를 복원 하 는 기호 표 에 정적 라 이브 러 리 정보 가 없 기 때 문 입 니 다.
정적 라 이브 러 리 는 컴 파일 만 있 고 링크 가 없 는 과정 이라는 것 을 알 고 있 습 니 다.
실제 바 이 너 리 패 키 지 를 칠 때 만 링크 작업 을 할 수 있 습 니 다.
기호 표 에 정적 라 이브 러 리 정보 가 없고 정적 라 이브 러 리 의 framework 에 코드 줄 수 에 대한 정보 가 없습니다!
공식 문 서 를 조회 한 결과 Generate Debug Symbols 의 속성 설명 은 다음 과 같 습 니 다.
Enables or disables generation of debug symbols. When debug symbols are enabled, the level of detail can be controlled by the Debug Information Format (DEBUG_INFORMATION_FORMAT) setting.
정적 라 이브 러 리 프로젝트 가 이 속성 을 NO 로 설정 하면 포 장 된 프레임 워 크 는 Debug 용 정 보 를 포함 하지 않 습 니 다.
문제 복구:
Generate Debug Symbols 설정 을 수정 합 니 다.

올 바른 설정
첨부:
Xcode 관련 설정 문 서 는 여기,이곳 링크 를 직접 클릭 합 니 다.효력 이 없 으 면 다음 절차 에 따라 찾 을 수 있 습 니 다.

Xcode 설정
UITableView 드 롭 다운 새로 고침 으로 인 한 애니메이션 이상
기능 배경:
UITableView 는 콘 텐 츠 를 보 여 주 는 데 사 용 됩 니 다.scrollView 에 RefreshHeadrView 를 추가 하여 드 롭 다운 리 셋 을 실현 합 니 다.
질문 설명:
현재 드 롭 다운 리 셋 후 Cell 내부 의 보 기 는 이동 합 니 다.유사 한 효 과 는 다음 과 같 습 니 다.(보 여주 기 위해 드 롭 다운 리 셋 대신 단 추 를 누 르 십시오)

관련 실현:
RefreshHeadrView(드 롭 다운 리 셋 view)는 scrollView 의 didScroll 리 셋 을 감청 하여 드 롭 다운 리 셋 을 촉발 합 니 다.끝 날 때 scrollView.contentInset 을 수정 하여 리 셋 이 완료 되면 자동 으로 미 끄 러 지 는 동작 을 수행 합 니 다.
드 롭 다운 새로 고침 이 끝 난 코드 는 다음 과 같 습 니 다:

  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationDuration:0.2];
  [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
  scrollView.contentInset = UIEdgeInsetsMake(-REFRESH_TRIGGER_HEIGHT + _initTopContentInset, 0.0f, 0.0f, 0.0f);
  [UIView commitAnimations];
질문 위치:
먼저 문제 의 표현 을 봅 니 다:UITableView Cell 의 보 기 는 새로 고침 후 이동 합 니 다.
변위 의 원인 은 여러 가지 가능성 이 있 습 니 다.동료 오 스 틴 은 해결 방안 을 제 공 했 습 니 다.드 롭 다운 새로 고침 한 후에 reloadData 를 다음 runloop 에 놓 고 실행 합 니 다.
시도 한 후에 과연 이 문 제 를 복구 하 였 습 니 다!
오 스 틴 의 해결 방안 은 나 로 하여 금 문제 가 반드시 현재 runloop 에서 하 는 작업 에 나타 나 서 UITable View Cell 의 보기 위 치 를 이동 시 켰 다 는 것 을 확인 하 게 했다.
테스트 를 통 해 문제 의 전체 경 로 를 거 슬러 올 라 갑 니 다.
  • 1.드 롭 다운 리 셋=>2.데이터 요청=>3.로 컬 데이터 원본 업데이트==>4.1 호출 reloadData 업데이트 보기
  • 3.로 컬 데이터 원본 업데이트==>4.2 드 롭 다운 리 셋 종료 didfinish==>4.3refreshHeaderView 종료 애니메이션==>4.4 트리거 didScroll
    리 셋==>4.5 리 셋 에서 visiable Cell 호출=>4.6 트리거 cellFor 방법=>4.7 UITableView Cell 초기 화 는 frame
  • 을 변경 합 니 다.
    보기 의 변위 원인 은 4.3 의 끝 에 있 습 니 다.애니메이션 은 UIView 의 애니메이션 트 랜 잭 션 에서 작 동 되 고 4.7 의 frame 변경 작업 은 애니메이션 트 랜 잭 션 에서 도 작 동 되 기 때문에 보기 의 애니메이션 효 과 를 촉발 합 니 다.
    문제 복구:
    복구 방안 은 dispatch 에서 다음 runloop 으로 reloadData 를 실행 할 수 있 습 니 다.이렇게 4.5 반전 에서 visiable Cell 을 호출 할 때 visiable Cell 은 지난번 cell 을 가 져 올 수 있 습 니 다.그러면 링크 가 끊 어 지고 보기 의 변위 가 발생 하지 않 습 니 다.하지만 버그 숨 기기:데이터 원본 과 UI 가 일치 하지 않 습 니 다!!
    최 적 솔 루 션:visiable Cell 을 사용 하지 않 고 현재 표 시 된 cell 을 가 져 옵 니 다.UITable View 를 감청 하 는 will Display 와 didEndDisplaying Cell 방법 으로 바 꾸 고 두 개의 엔 드 대기 열 로 현재 보 이 는 cell 을 유지 합 니 다.
    이 문 제 를 통 해-reloadData 방법 은 UITableView 의 보 이 는 cell 을 비 우 는 것 임 을 확인 할 수 있 습 니 다.
    visiable Cell 은 getter 입 니 다.호출 할 때 visiable Cell 이 비어 있 으 면 cellfor 방법 을 초기 화 합 니 다.
    Crash 포 지 셔 닝
    실제 개발 에서 발생 한 Crash 문제 에서 비롯 되 었 습 니 다.스 택 은 다음 과 같 습 니 다.

    crash 문 제 는 각 iOS 버 전에 서 발생 합 니 다.매일 crash 율(crash 횟수/사용자 수)은 만 분 의 1.5 정도 입 니 다.
    crash 를 통한 설명 platformmemmove,그리고 스 택 정 보 는 코드 이상 이 memcpy 에 나타 난 함수 임 을 찾 을 수 있 습 니 다.
    오류 형식 을 통 해 우 리 는 불법 메모리 주 소 를 방문 하 는 것 을 알 고 있 습 니 다.
    memcpy 는 모두 세 개의 매개 변수 가 있 습 니 다.함 수 를 실행 할 때 세 개의 매개 변 수 를 x0,x1,x2 세 개의 레지스터 에 넣 습 니 다.crash 로그 의 레지스터 정 보 를 통 해 우 리 는 이 세 개의 매개 변수의 값 을 얻 을 수 있 습 니 다.다음 과 같 습 니 다.
    
    Thread 0 crashed with ARM Thread State (64-bit):
     x0: 0x00000000000000aa x1: 0x00000000000000bb x2: 0x00000000000000cc x3: 0x00000000000000c0
     x4: 0x0000000000000010 x5: 0x0000000000000002 x6: 0x0000000000000064 x7: 0x0000000000000000
     x8: 0x00000000000000aa x9: 0x0000ddf9664f0000 x10: 0x0000000000004887 x11: 0x00000001b8741211
     x12: 0x00000001b8741211 x13: 0x000000000000001d x14: 0x0000000000000001 x15: 0x0000000000000881
     x16: 0x00000001855b1ab0 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x00000000000000aa
     x20: 0x0000000119d064f0 x21: 0x0000000000000018 x22: 0x000000018fb4dd6a x23: 0x0000000000000000
     x24: 0x0000000000000010 x25: 0x0000000119e01b40 x26: 0x0000000000000280 x27: 0x0000000119d06c50
     x28: 0x0000000000000001 fp: 0x000000016bce95f0 lr: 0x000000018542ce58
     sp: 0x000000016bce95f0 pc: 0x00000001855b1b60 cpsr: 0x80000000
    위의 레지스터 정 보 를 통 해 우 리 는 x0,x1,x2 의 레지스터 값 을 0xAA,0xBB,0xCC 로 가 져 와 서 crash 를 야기 하 는 함 수 를 memcpy(0xaa,0xbb,0xcc)로 복원 할 수 있다.
    (여기 memcpy 의 세 가지 매개 변 수 는 제 가 특별히 구성 한 것 으로 문 제 를 설명 할 수 있 습 니 다)
    여기에 두 가지 crash 가능성 이 있 습 니 다.
    1.매개 변수 1 쓰기 데이터 불법;
    2.매개 변수 2 읽 기 데이터 불법;
    먼저 비슷 한 문 제 를 보 겠 습 니 다.아래 코드 에 무슨 문제 가 있 습 니까?
    
    int *p1=malloc(1024);
    int *p2=malloc(1024);
    memcpy(p1, p2, 1025);
    정 답 은 대부분의 경우 정상적으로 운행 되 고,소수의 경우 Crash 가 된다 는 것 이다.
    Crash 는 본질 적 으로 메모리 접근 이 경 계 를 넘 지만 메모리 공간 에서 스 택 메모리 공간 까지 의 거리 가 고정 되 지 않 습 니 다.p1+1025 에 쓰기 권한 이 있 으 면 p2+1025 에 읽 기 권한 이 있 으 면 crash 가 발생 하지 않 습 니 다.

    첨부:
    실제 개발 에서 레지스터 x2+레지스터 x5 의 값 이 야 말로 진정한 memcpy 의 세 번 째 매개 변수 입 니 다.
    x2: 0x00000000000003e0 + x5: 0x0000000000000020 = 0x0000000000000400 = 1024
    애플 이 memcpy 방법 을 수정 한 것 으로 의심 된다.
    두 번 째 매개 변수 가 메모리 주 소 를 쌓 을 때 차단 합 니 다.
    두 번 째 매개 변수 가 불법 주소 일 때(예 를 들 어 0x00000000000bb)는 절단 하지 않 습 니 다.
    총결산
    문 제 를 만 나 는 것 은 정상 적 인 것 이다.문 제 를 해결 하 는 것 에서 지식 을 배우 고 문제 로 지식 을 검증 할 수 있다 면 문 제 는 학습 발전의 일부분 이 될 수 있다.
    자,이상 이 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기