简体   繁体   中英

Passing optional @objc enum type into @objc protocol

I'm trying to create an optional function in @objc protocol, The documentType is @objc enum as well. But I'm getting this error:

Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C

My source code:

@objc enum DocumentType: Int {
    case pdf
    case png
}

@objc protocol ImageDocumentEditorProtocol: class {
    @objc optional func imageDocumentEditorDidCancel(documentType: DocumentType?)
}

How can I solve this issue? Thanks

The problem is ? .

In Objective-C, you cannot represent an Optional of primitive types.

Make it non-Optional, or find another way.

Just remove the optional on the DocumentType so the function will be:

@objc optional func imageDocumentEditorDidCancel(documentType: DocumentType)

if you want to have something representing the nil value here you can add another case in the enum for it like this:

@objc enum DocumentType: Int {
    case pdf
    case png
    case none
}

Objective-C doesn't have optional enums. Enums must be non-optional. Classes can be optional, not enums:(

One workaround is to add a case:

@objc enum DocumentType: Int {
    case pdf
    case png
    case none
}

And use the non-optional type DocumentType instead.

Of course, this makes non-optional DocumentType s non-representable. To represent both optional and non-optional DocumentType s, you would need two types:

@objc enum DocumentType: Int {
    case pdf
    case png
    
    func asOptionalDocumentType() -> OptionalDocumentType {
        switch self {
        case .pdf: return .pdf
        case .png: return .png
        }
    }
}

extension Optional where Wrapped == DocumentType {
    func asOptionalDocumentType() -> OptionalDocumentType {
        self?.asOptionalDocumentType() ?? .none
    }
}

@objc enum OptionalDocumentType: Int, ExpressibleByNilLiteral {
    
    case pdf
    case png
    case none
    
    func asDocumentType() -> DocumentType? {
        switch self {
        case .pdf: return .pdf
        case .png: return .png
        case .none: return nil
        }
    }
    
    init(nilLiteral: ()) {
        self = .none
    }
}

I have added conversion methods to make it easy to convert between them, but they are not technically needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM