Unable to use custom class in a protocol with @obj

2019-02-12 15:54发布

问题:

I am trying to create a protocol for JSON loading delegation, JSONLoaderDelegate. My other class, called JSONLoader, is supposed to dispatch events to its delegate (that implements the JSONLoaderDelegate protocol) like:

self?.delegate?.jsonLoaderdidEndWithError(self!, error: JSONLoaderError.LoadError)

The implementation of the JSONLoader is not that important (imho). However I seem to have problems to implement the protocol, this is the code:

@objc protocol JSONLoaderDelegate {

    optional func jsonLoaderdidBeginLoading(jsonLoader: JSONLoader)
    func jsonLoaderdidEndWithError(jsonLoader: JSONLoader, error: JSONLoader.JSONLoaderError)
    func jsonLoaderDidEndWithSuccess(jsonLoader: JSONLoader)

}

This looks pretty straightforward to me but I am getting an error:

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

pointed to all three functions.

Obviously, if I remove the @objc attribute I cannot use the optional for the function. I would really like to keep jsonLoaderdidBeginLoading as optional tho. Any ideas / ways to solve this? Thank you!

回答1:

What the 3 methods have in common is the JSONLoader parameter, and that's what I think prevents you from bridging the protocol. In order to solve the problem you have to make it objc compatible.



回答2:

I faced this problem as I had a class MyConnection that had no parent class. Like this.

public class MyConnection {
}

I can't put @objc before this, as I get a warning

Only classes that inherit from NSObject can be declared @objc

So I changed the class to be inherited from NSObject. Like this

public class MyConnection: NSObject {
}


回答3:

I had the same error. method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C.

I changed the syntax to the following in swift 2.0. It works fine now!

@objc protocol AppModelDelegate {
    optional func compititorList(com:[Competitor]!)
}

class Competitor:NSObject{
    var id:Int?
    var title:String?
}

Note: the Competitor class type changed to NSObject which cleared the delegate rule violation

Also in the case of NSJSON parsing. I changed to the following.

if (_httpStatusCode == 200) {
    let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
    var error : NSError?
    print("responseString : \(responseString) ")

    var service_result:NSDictionary =  NSDictionary()
    do {
        let anyObj = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as! [String:AnyObject]
        service_result = anyObj
    } catch let error as ErrorType {
        print("json error: \(error)")
    }
}


回答4:

JSONLoaderError.LoadError

Is this an enum type? You cannot convert Swift enums to Obj-C code. You'll need to use an int instead.