Objective-C 코드가 Class에서 신속한 확장을 호출 할 수 있습니까?


94

일부 게시물을 검색했는데 신속하게 확장 기능을 작성할 수 없다고 생각하고 Objective-C 코드에서 호출 할 수 있습니까?

@objc와 같은 속성은 메서드, 클래스, 프로토콜 만 지원합니까?


1
그냥 시도해 보는 게 어때?
— HAS

7
ide가 오류를 불평했지만 확실한 답변을 얻고 싶습니다.
— sprhawk 2014

답변:


84

Swift 확장을 작성하여 Objective-C 코드에서 사용할 수 있습니다. XCode 6.1.1로 테스트되었습니다.

당신이해야 할 일은 :

  • Swift에서 확장 기능 생성 ( @objc주석 없음 )

  • #import "ProjectTarget-Swift.h" Objective-C 클래스에서 ( "ProjectTarget"은 Swift 확장과 연관된 XCode 대상을 나타냄)

  • Swift 확장에서 메소드 호출

업데이트 : @Rizwan Ahmed가 언급했듯이 @objc주석 을 추가해야합니다 .

Swift 4.0.3부터 Objective C 클래스 파일에서 확장을 사용하려면 @objc 주석이 필요합니다.


6
정확히이 작업을 수행했지만 여전히 컴파일 시간 오류입니다. 흠. 편집 : "ProjectTarget-Swift.h" 대신 브리징 헤더를 가져 왔습니다 . Der.
— Jason Renaldo

둘 다 브리징 헤더입니다. 차이점은 하나는 ObjC에서 Swift 코드를 사용하기위한 것이고 다른 하나는 Swift에서 ObjC 코드를 사용하기위한 것입니다. Swift 헤더는 보이지 않습니다. 다른 하나는 귀하가 관리해야합니다.
— marius bardan

William Hu, mclaughlinj의 답변을 참조하십시오!
— appleitung apr

39
Swift 4.0.3부터 Objective C 클래스 파일에서 확장을 사용하려면 @objc 주석이 필요합니다.
— Rizwan Ahmed

69

나는 Swift 4.0에서 내가 확장하고있는 Objc 클래스의 인스턴스에서 Swift 확장 메소드를 볼 수 있도록하기 위해 확장 키워드 @objc앞에 추가해야한다는 것을 알았습니다 .

요컨대 :

파일 구성 설정 :

CustomClass.h
CustomClass.m
CustomClassExtension.swift

CustomClassExtension에서 :

@objc extension CustomClass
{
    func method1() 
    {
        ...
    }
}

내 AppDelegate.m에서 :

self.customClass = [[CustomClass alloc] init];
[self.customClass method1];

2
메서드가 제네릭을 사용하는 경우 Objective-C에서 사용할 수 없으며 @nonobjc주석 을 추가해야합니다 .
— ThomasW

이 경우 @objcMembers는 작동하지 않습니다. 이유를 모르겠어요 .. :-(
— Raunak

46

이 솔루션은 Swift 2.2 및 Swift 3에서 작동합니다 . Objective-C에서는 클래스 용 확장 (구조체 또는 열거 형 제외) 만 액세스 할 수 있습니다.

import UIKit

extension UIColor {

    //Custom colours
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

그런 다음 ObjC 파일에서 "ProductModuleName-Swift.h" 를 #import 합니다.

스위프트 4

extension UIColor {

    // As of Swift 4.0.3, the @objc annotation is needed if you want to use the extension in Objective-C files
    @objc
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

"YourProjectsNameHere ..."가 아니라 "YourTargetsNameHere ..."입니다. 대상을 공유하려면 다음 이름으로 잠 가야합니다
— Dan Rosenstark 2015

1
@DanRosenstark 맞습니다. : 애플에서 알 수 있듯이 나는 "ProductModuleName-Swift.h"로 변경하고 developer.apple.com/library/ios/documentation/Swift/Conceptual/...
— Foti 희미한

1
스위프트 3에서 잘 작동합니다.
— Viktor Kucera 2016

public필요 하다고 말하는 이유 가 있습니까? public나를 위해 수정 자 없이 잘 작동합니다 . 확장이 동일한 프로젝트에 있지 않고 다른 프로젝트에서 가져 온다고 가정합니까?
— 리 강

브리징 헤더를 사용해야합니까?
— jegadeesh

42

다른 답변에서 다루었 듯이 생성 된 Swift 헤더를 가져 오는 것은 대부분의 경우 작동합니다 .

이에 대한 예외는 범주가 브리지 된 유형에 정의 된 경우입니다 (예 : 확장이에 정의되어 String있고에 정의되어 있지 않음 NSString). 이러한 범주는 Objective-C 대응 범주에 자동으로 연결되지 않습니다. 이 문제를 해결하려면 Objective-C 유형을 사용하거나 (그리고를 사용하여 Swift 코드에서 반환 값을 캐스트 as String) Swift 및 Objective-C 유형 모두에 대한 확장을 정의해야합니다.


2
위의 답변에 추가하여 신속한 확장을 공개하고 유형을 NSString 예를 들어 설정해야합니다 public extension NSString. 컴파일 타임에 해결되지 않은 식별자 또는 유사한 오류가 발생하면 다시 String으로 다시 캐스팅 let sVal = self as String한 다음 필요한 코드를 호출 할 수 있습니다.sVal
— RunLoop

@RunLoop 실제로는 공용이 필요하지 않으며 범위 지정자없이 작동합니다. 그리고 그것은 (Obj-C로 내보내기) Strings에서 작동하지 않습니다. 왜냐하면 그것들은 클래스가 아니라 구조체이기 때문이며 Swift에서만 사용할 수 있습니다. 그래서, 예 - 당신은있는 NSString 사용 캐스트 또는 쓰기 확장을위한 확장을 작성할 수 있습니다 mclaughlinj말했다는 NSString 클래스와 문자열 구조체 모두,
— 알렉스 Nazarsky

3

가져 오기 "# import를"ProductModuleName-Swift.h " 목표 - C 파일의 헤더와 추가 @objc 당신의 뿅 extentsion 신속한 파일을. 그것은 빠른 4.2 빠른 5에서 잘 작동합니다

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