Swift에서 @objc를 언제 사용합니까?


87

Swift에서는 다음과 같은 방법이 있습니다.

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)

@objc를 언제 사용할지 궁금합니다. 일부 문서를 읽었지만 Objective-C에서 호출 가능하도록하려면 @objc 플래그를 추가해야한다고 말합니다.

그러나 이것은 Swift의 private 함수입니다. @obj는 무엇을합니까?


1
좋은 질문 !!!
Erhan Demirci

답변:


67

private은 Swift에서만 볼 수 있음을 의미합니다. 따라서 @objc를 사용하여 Objective-C에서 볼 수 있습니다. swift에서 private func를 선택하는 func가 있으면 필요합니다.

@objc 속성은 Objective-C 및 Objective-C 런타임에서 Swift API를 사용할 수 있도록합니다.

참조 : https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html


1
그래서 @objc private func doubleTapGestureRecognized@objc와 개인을 모두 갖는 요점은 무엇입니까? Objective-C 클래스가 doubleTapGestureRecognized를 덮어 쓸 수 있다는 말입니까?
Wingzero

1
obj-c에서는 어쨌든 모든 메서드를 덮어 쓸 수 있기 때문이라고 생각합니다.
strangetimes

2
이 대답이 옳은지 그리고 그의 Q에 대한 대답은 확실하지 않습니다. 여기에 제공된 ans는 이미 그의 Q 자체에 있습니다. "하지만 Objective-C에서 호출 할 수 있도록하려면 \ @objc 플래그를 추가해야합니다." Q는 "이것은 swift의 private 함수입니다. \ @obj는 무엇을합니까?"
KBJ

3
링크가 끊어집니다. 특히 Apple 문서에. 여기에있는 문서에서 핵심 요소를 추출해보십시오.
levigroker

55

또 다른 늦은 답변이지만이 질문에 대한 기존 답변은 실제로 OP의 질문에 대한 답변이 없습니다. 즉 , Objective-C와의 상호 작용을 위해 클래스 구성원 에게 도대체를 사용해야 @objc하는 이유 와 문제의 구성원 프로젝트에 Objective-C 코드가 있어도 멤버를 볼 수 없어야한다는 의미입니다.private@objc

그 이유는 많은 프레임 워크가 Objective-C로 작성 되었기 때문에 때때로 특정 API와 상호 작용하기 위해 Objective-C 기능이 필요하기 때문입니다.

예를 들어 다음을 통해 알림을 등록한다고 가정합니다 DistributedNotificationCenter.

DistributedNotificationCenter.default.addObserver(self,
                                                  selector: #selector(somethingHappened(_:)),
                                                  name: someNotification,
                                                  object: nil)

이것이 작동하려면 somethingHappened메서드에 대한 선택기를 가져올 수 있어야합니다 . 그러나 선택기는 Objective-C 개념이므로 메서드가 Objective-C에 표시되지 않으면 선택기가 없습니다. 따라서, 상기 방법은 전용이며, 임의의 외부 코드에 의해 호출되지 않아야하는 경우에도, 그것은 필요하다 @objc위해서는 DistributedNotification셀렉터를 통해 전화를 할 수 있도록, 목표-C로 작성된 코드.

@objc필요한 또 다른 일반적인 경우 는 KVC (Key-Value Coding)를 지원하는 것입니다. 특히 macOS에서 KVC와 KVO가 Cocoa 바인딩을 구현하는 데 사용됩니다. KVC는 Cocoa의 다른 많은 시스템과 마찬가지로 Objective-C로 구현되어 KVC 호환 속성이 ​​Objective-C 런타임에 노출되도록 요구하는 효과가 있습니다. 때로는 KVC 호환 속성이 ​​비공개 인 것이 타당합니다. 한 가지 예는 다른 속성에 영향을주는 속성이있는 경우입니다.

@objc private dynamic var originalProperty: String

@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
    #keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }

이 경우, 우리의 실제 저장된 속성은 개인이지만, 우리가 종속 재산 않는 외부 코드에 노출은 사유 재산이 업데이트 될 때 그 알림을 보낼 필요가있다. 개인 속성을으로 표시하면 @objcKVC 종속성을 설정하여 쉽게 수행 할 수 있습니다. 그렇지 않으면 개인 속성 willSetdidSet처리기 에서 수동으로 알림을 보내는 코드를 작성해야합니다 . 또한 dependentProperty종속 된 KVC 시스템에 알리는 정적 속성은 originalPropertyObjective-C에 노출되어 KVC 시스템이 찾아서 호출해야하지만 우리 코드의 클라이언트와 관련이 없습니다.

또한 Cocoa Bindings를 구현 세부 사항으로 사용하여 뷰에서 컨트롤을 업데이트하는 macOS 앱의 뷰 컨트롤러는 해당 컨트롤을 바인딩하기 위해 특정 개인 속성 KVC를 준수하도록 만들 수 있습니다.

보시다시피, 프레임 워크와 상호 작용하기 위해 코드의 클라이언트에게 반드시 표시 될 필요없이 메서드 또는 속성이 Objective-C에 노출되어야하는 경우가 있습니다.


25

@objc / 동적

호환성을위한 것입니다. 일단 Swift 파일 / 코드를 Objective-C 기반 프로젝트로 가져옵니다.

Objective-C 코드 또는 클래스에서 속성 / 메서드에 액세스하려면이를 사용하십시오.

대부분의 경우 Objective-C 기본 클래스의 Swift 클래스를 하위 클래스화할 때 발생합니다.

Swift 클래스 또는 프로토콜은 Objective-C에서 액세스 및 사용 가능 하도록 @objc 속성 으로 표시되어야합니다 . 이 속성은 Objective-C에서이 Swift 코드에 액세스 할 수 있음을 컴파일러에 알려줍니다. Swift 클래스가 Objective-C 클래스의 자손 인 경우 컴파일러는 자동으로 @objc 속성을 추가합니다.

여기에 대해 말하는 사과 문서 @objc.

Objective-C에서 Swift 사용

언어 상호 운용성 호환성

업데이트 된 링크 :
애플에서 링크를 업데이트 한 것 같습니다.


11

@objc는 클래스 속성이므로

@objc public class MyClass

클래스의 메서드를 Objective C 클래스에 노출하므로 클래스에 공용 함수가 포함 된 경우에만 사용합니다.


7

늦은 답변이지만이 @objc동작은 Swift 4 (일반적으로 10 일 전에 출시 된 Xcode 9에서 나옴)부터 약간 변경됩니다.

Swift 4에서는의 일부 추론 사례 @objc가 제거되었습니다. 이것은 @objc헤더가 Swift 컴파일러에 의해 추론 되기 전에 추론되지 않은 Swift 4에 있는 일부 추가 경우를 의미 합니다.

이 변경 사항 에 대한 Swift 진화 제안에서 자세히 읽어보십시오.

앞서 언급했듯이 일반적으로 @objc특정 메서드를 Objective-C 런타임에 노출하는 것입니다. 이는 Swift의 상호 운용성 언어의 일부입니다.


1
그래서 이것이 Swift 4로 업데이트 한 후 ObjC에서 일부 변수에 액세스 할 수없는 이유입니다. Swift 3.X를 사용하면 추가 할 필요가 없었습니다@objc
rgkobashi

오 그래, 항상 다른 사람과 다시 확인하는 것이 좋습니다. 감사합니다!
rgkobashi

1

@objc선언을 Objective-C runtime. #selectorObjective-C 런타임을 사용하는 Swift의 기능을 살펴 보겠습니다 . 이 경우 Swift를 정의 할 수 있습니다. @objc private func[More]

Objective-C에서 Swift의 기능을 사용하려면 :

  1. Swift의 클래스는 NSObject
  2. Mark Swift의 :

    ㅏ. @objcMembers 클래스 전용- 모든 public 생성자 , 필드메서드 를 노출 합니다 . 또한 하위 클래스에도 적용 가능합니다.

    비. @objc 클래스 / 열거 형 / 프로토콜 ( 구조체 제외 ) [명명 된 유형]

    • @objc class (선택 사항)- 기본 public init() . 또는 @objc(<custom_name>)클래스의 사용자 지정 이름을 설정합니다.
    • @objc 생성자 , 필드메서드 -선택적으로 노출

Swift의 방법은 다음 이름으로 사용할 수 있습니다.

<swiftName>With<firstArgument>:<secondArgument>:

예를 들면 :

public func printHelloWorld(arg1: String, arg2:String)
//is reached through: 
[someObject printHelloWorldWithArg1: arg2:];

[ @objcdynamic]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.