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.