Swift Language
C 및 Objective-C 작업
수색…
비고
더 자세한 정보는 Sweet와 Cocoa 및 Objective-C 사용 에 대한 Apple의 설명서를 참조하십시오.
Objective-C 코드의 Swift 클래스 사용
동일한 모듈에서
" MyModule "이라는 모듈 내에서 Xcode는 공용 Swift 클래스를 Objective-C로 노출시키는 MyModule-Swift.h
라는 헤더를 생성합니다. Swift 클래스를 사용하려면이 헤더를 가져옵니다.
// MySwiftClass.swift in MyApp
import Foundation
// The class must be `public` to be visible, unless this target also has a bridging header
public class MySwiftClass: NSObject {
// ...
}
// MyViewController.m in MyApp
#import "MyViewController.h"
#import "MyApp-Swift.h" // import the generated interface
#import <MyFramework/MyFramework-Swift.h> // or use angle brackets for a framework target
@implementation MyViewController
- (void)demo {
[[MySwiftClass alloc] init]; // use the Swift class
}
@end
관련 빌드 설정 :
- Objective-C 생성 된 인터페이스 헤더 이름 : 생성 된 Obj-C 헤더의 이름을 제어합니다.
- Objective-C 호환성 헤더 설치 : -Swift.h 헤더가 공개 헤더 여야하는지 여부 (프레임 워크 대상).
다른 모듈에서
@import MyFramework;
사용 @import MyFramework;
Obj-C 인터페이스를 포함한 전체 모듈을 Swift 클래스로 가져옵니다 (위에서 설명한 빌드 설정이 활성화 된 경우).
Swift 코드의 Objective-C 클래스 사용
MyFramework에 공용 헤더 (및 우산 머리글)에 Objective-C 클래스가 포함되어 있으면 Swift에서 import MyFramework
있으면됩니다.
브리징 헤더
브리징 헤더를 사용하면 Swift 코드에서 Objective-C 및 C 선언을 볼 수 있습니다. 프로젝트 파일을 추가 할 때 Xcode는 자동으로 브리징 헤더를 만들 수 있습니다.
수동으로 만들려면 Objective-C 브리징 헤더 빌드 설정을 수정하십시오.
브리징 헤더 내에서 코드에서 사용할 파일을 가져옵니다.
// MyApp-Bridging-Header.h
#import "MyClass.h" // allows code in this module to use MyClass
생성 된 인터페이스
관련 항목 버튼을 클릭하거나 ^ 1을 누른 다음 생성 된 인터페이스 를 선택하여 Objective-C 헤더에서 생성되는 Swift 인터페이스를 확인합니다.
swiftc에 브리징 헤더 지정
-import-objc-header
플래그는 가져올 swiftc
의 헤더를 지정합니다.
// defs.h
struct Color {
int red, green, blue;
};
#define MAX_VALUE 255
// demo.swift
extension Color: CustomStringConvertible { // extension on a C struct
public var description: String {
return "Color(red: \(red), green: \(green), blue: \(blue))"
}
}
print("MAX_VALUE is: \(MAX_VALUE)") // C macro becomes a constant
let color = Color(red: 0xCA, green: 0xCA, blue: 0xD0) // C struct initializer
print("The color is \(color)")
$ swiftc demo.swift -import-objc-header defs.h && ./demo MAX_VALUE is: 255 The color is Color(red: 202, green: 202, blue: 208)
모듈 맵을 사용하여 C 헤더 가져 오기
모듈 맵 은 C 헤더 파일을 읽고 Swift 함수로 나타나도록 구성하여 import mymodule
을 간단히 import mymodule
수 있습니다.
mymodule
디렉토리에 module.modulemap
이라는 파일을 저장합니다.
모듈 맵 파일 내부 :
// mymodule/module.modulemap
module mymodule {
header "defs.h"
}
그런 다음 모듈을 import
.
// demo.swift
import mymodule
print("Empty color: \(Color())")
swiftc
에게 모듈을 찾을 위치를 알려주 swiftc
-I directory
플래그를 사용하십시오 :
swiftc -I . demo.swift # "-I ." means "search for modules in the current directory"
모듈 맵 구문에 대한 자세한 내용은 모듈 맵에 대한 Clang 설명서를 참조하십시오.
Objective-C와 Swift 간의 세밀한 상호 운용
API가 NS_REFINED_FOR_SWIFT
로 표시되면 Swift로 가져올 때 접두어가 두 개의 밑줄 ( __
)로 표시됩니다.
@interface MyClass : NSObject
- (NSInteger)indexOfObject:(id)obj NS_REFINED_FOR_SWIFT;
@end
생성 된 인터페이스 는 다음과 같습니다.
public class MyClass : NSObject {
public func __indexOfObject(obj: AnyObject) -> Int
}
이제 API 를 더 "Swifty"확장 프로그램으로 대체 할 수 있습니다. 이 경우 선택적 반환 값을 사용하여 NSNotFound를 필터링 할 수 있습니다.
extension MyClass {
// Rather than returning NSNotFound if the object doesn't exist,
// this "refined" API returns nil.
func indexOfObject(obj: AnyObject) -> Int? {
let idx = __indexOfObject(obj)
if idx == NSNotFound { return nil }
return idx
}
}
// Swift code, using "if let" as it should be:
let myobj = MyClass()
if let idx = myobj.indexOfObject(something) {
// do something with idx
}
대부분의 경우 Objective-C 함수에 대한 인수가 nil
이 될 수 있는지 여부를 제한하려고 할 수 있습니다. 이것은 포인터 또는 블록 참조를 규정하는 _Nonnull
키워드를 사용하여 수행됩니다.
void
doStuff(const void *const _Nonnull data, void (^_Nonnull completion)())
{
// complex asynchronous code
}
작성된 것으로 컴파일러는 Swift 코드에서 해당 함수에 nil
을 전달하려고 시도 할 때마다 오류를 내 nil
.
doStuff(
nil, // error: nil is not compatible with expected argument type 'UnsafeRawPointer'
nil) // error: nil is not compatible with expected argument type '() -> Void'
반대 _Nonnull
있다 _Nullable
그것을 통과하는 것을 허용되는 의미 nil
이 인수. _Nullable
도 기본값입니다. 그러나이를 명시 적으로 지정하면 더 많은 자체 문서화되고 미래 보장적인 코드가 허용됩니다.
코드를 최적화하여 컴파일러를보다 잘 돕기 위해 블록이 이스케이프 처리 중인지 여부를 지정할 수도 있습니다.
void
callNow(__attribute__((noescape)) void (^_Nonnull f)())
{
// f is not stored anywhere
}
이 속성을 사용하여 블록 참조를 저장하지 않고 함수 실행이 완료된 후에 블록을 호출하지 않을 것을 약속합니다.
C 표준 라이브러리 사용
Swift의 C 상호 운용성을 통해 C 표준 라이브러리의 함수와 유형을 사용할 수 있습니다.
Linux에서 C 표준 라이브러리는 Glibc
모듈을 통해 공개됩니다. 애플 플랫폼에서는 Darwin
이라고 불린다.
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
import Darwin
#elseif os(Linux)
import Glibc
#endif
// use open(), read(), and other libc features