[TIL]01.27

rbw·2023년 1월 27일
0

TIL

목록 보기
69/97

ABI(Application Binary Interface)

참조

https://seokba.tistory.com/10


  • 바이너리 간 인터페이스
  • 런타임에 Swift 프로그램 바이너리는 다른 라이브러리와 ABI를 통해 상호작용합니다.
  • 운영체제와 앱, 앱과 라이브러리간 상호작용을 위해 ABI를 사용하게 됩니다.
  • ABI에는 함수를 어떻게 호출할지, 메모리에 데이터를 어떻게 표현할지, 메타데이터를 어디에 놓고 어떻게 접근할지 등을 정의합니다.

  • 기계코드(machine code)에 대한 통신 규칙 정의
    • CPU instructions(registers, stack organization, memory access tyep) CPU 명령어
    • calling convention(함수 호출, argument전달, 값 리턴)
    • OS에 대한 시스템 호출
    • Data Layout
    • Type Metadata
    • Mangling
    • Runtime
    • Standara Library

Source Compatibility

  • 소스 호환성(== API Stable)
  • 버전에 상관없이 소스들을 호환시킬 수 있음
  • Swift 개발자가 새로운 Swift 버전이 나왔을 때, 새 버전으로 마이그레이션 해야 하는 경우의 번거로움을 줄여준다.

Binary Framework & Runtime Compatibility

  • 여러 Swift 버전에서 작동하는 binary form의 프레임워크를 배포할 수 있게 하는 것
  • 바이너리 프레임워크에는 프레임워크 API의 소스레벨 정보를 전달하는 스위프트 모듈파일과 런타임에 로드되는 컴파일 된 구현을 제공하는 공유 라이브러리가 모두 포함(Binary Framework = Swift 모듈 파일 + 공유 라이브러리)
  • Module Format Stability(모듈 형식 안정성)
    • 프레임워크 공용 인터페이스에 대한 컴파일러의 표현인 모듈 파일을 안정화(API 선언 및 inlineable 코드가 포함)
    • 모듈 파일
      • 프레임워크를 사용하여 클라이언트 코드를 컴파일할 때, 타입 검사 및 코드 생성과 같은 필요한 작업을 위해 컴파일러에서 사용

ABI Stability

  • ABI가 안정화 되었다 == 앞으로 ABI가 변하지 않을 것
  • 바이너리의 내부 처리 방식은 바뀔 수 있지만 인터페이스는 유지된다는 것
  • 이것이 지원되면 Swift 컴파일러로 컴파일한 앱과 이후 업데이트 된 Swift 컴파일러로 컴파일된 라이브러리의 바이너리간 호환이 가능
  • Swift 5.0 미만의 Swift는 ABI stable 하지 않음
    • 그래서 각 바이너리 번들에는 고유의 Swift 동적 라이브러리(.dylib 파일)를 갖고 있고 이 라이브러리는 바이너리간 상호 작용을 위해 사용

ipa 파일 내부의 동적 라이브러리파일

  • Swift 5.0부터 ABI가 안정화 되었고 이후 Swift 표준 라이브러리를 iOS(운영체제 단)에 적용하면 ABI는 Swift 5.0 이후 모든 버전에서 호환되어 동작 가능

따라서 기존 앱 내에 존재했던 Swift 버전별 Dynamic Library가 OS의 일부로 포함 되게 되어 Swift 표준 dylib를 앱에 패키징할 필요가 없어짐
- 소스파일 대신 미리 컴파일된 프레임워크로 배포가 가능
- 외부 의존성을 프로젝트에 통합해야하는 경우, 기존보다 빌드시간이 빨라질 수 있음
- 아마도 앱 용량도 줄어들겠져 ?

Objective-C의 배열과 Swift 배열의 차이

참조

https://achievers.engineering/data-structures-and-algorithms-in-swift-arrays-c4ed2b44d238

간단하게만 살펴보았습니다. 위 글 맨 아래 문단

이 둘은 동일하지 않습니다. Swift의 배열은 값 유형이므로 전달될 때 복사되는 반면 Objective-C 배열은 참조 유형이므로 복사되지 않고, 개체에 대한 참조가 전달됩니다.

여기서 알아둬야 하는 점은 Swift 배열은 Copy-on-Write 라는 부분입니다. 이는 초기에는 참조만 전달이되어 값이 공유가 된다는 점입니다. 하지만 값의 변경이 일어난다면 원래 값을 수정하는 대신 복사본이 만들어지고 수정을 위해 전달됩니다.

또 차이점으로, Swift에는 배열 클래스가 없다는 부분입니다. 일반적으로 구조체를 사용하고 있습니다. 반대로 Objective-C에서는 클래스로 구현되어 있어서 배열이 가변인지 불변인지를 나타내는 별도의 클래스가 있습니다. 따라서 Swift에서 배열을 다루는 것은 Objective-C보다 훨씬 쉽습니다.

해쉬 충돌

참조

https://sihyungyou.github.io/iOS-hash-collision-swift/


딕셔너리의 내부 접근 시간 복잡도는 평균적으로 O(1)이나 해쉬 충돌이 일어나는 경우 최악에는 O(N)이다.

해쉬 충돌이란 서로 다른 두 입력 값(키 값으로 생각하면 됩니다)에 대해, 동일한 출력값을 내는 상황을 의미합니다.

이런 경우를 방지하기 위해 방법들이 있는데, 간단히 살펴보겠슴다.

첫 번째 방법으로는, 충돌이 일어난 경우에, 연결리스트를 이용하여 데이터를 추가로 뒤에 연결 시켜서 저장하는 체이닝 기법이 존재합니다.

두 번째 방법으로는, 충돌이 난 부분 다음 데이터로 아래로 순회하여, 빈 공간에 충돌이 일어난 데이터를 삽입하는 방법입니다. 이는 Linear Probing기법이라고 합니다.

생각을 조금 해보면 결국 이러한 예외들이 존재하기 때문에 해쉬 테이블을 사용한 딕셔너리의 접근 시간 복잡도의 최악은 O(N)이라는 것을 알 수 있었습니다 !

추가로 위 참조한 링크의 글에서 Swift는 Linear Probing 기법을 사용하여 해쉬충돌을 해결한다고 한다.

Hashable에서 ==을 구현해야 하는 이유도, 위와 연관지어서 추론하여 해쉬 충돌이 일어난 경우에, 해쉬값으로 비교하는게 아닌 다른요소로 동등성을 검사하여서 올바른 값을 출력하기 위해서 임을 알 수 있다

확실히 추론 잘하신다~


이번에는 여러 잡다한 부분들을 알아보았슴니다. 해쉬 충돌이나, 앱 용량에 관한 부분이 좀 인상깊었슴다~

profile
hi there 👋

0개의 댓글