Make a fast class compatible with the protocol - at a static / level level

I am trying to create a general subclass of UITableViewController in Swift that will accommodate any number of different types of table cells without having any internal knowledge of any of them.

For this I am trying to use protocols for my models and for my table cells. The protocol for models will return which class I should go to, and the protocol for cells will return answers to questions such as cell height for a given model.

But I have a problem with the work of protocols, because with the second protocol I want to go to the cell class, and not to its instance.

The protocol for the models is as follows:

protocol JBSTableItemDelegate { func tableCellDelegate() -> JBSTableViewCellInterface } 

The protocol for the cells is as follows:

 protocol JBSTableViewCellInterface: class { static func registerNibsWithTableView(tableView: UITableView) static func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath?, tableItem: JBSTableItemDelegate) -> CGFloat static func tableView(tableView: UITableView, dequeueReusableCellWithIndexPath indexPath: NSIndexPath, tableItem: JBSTableItemDelegate, delegate: AnyObject) -> JBSTableViewCell } 

Note the use of the static keyword. These methods are class methods in subclasses of UITableViewCell, and adding statics seems to be what I need to do to make sure these classes match or, as I understand it.

When I use the first protocol, the code looks like this and it compiles:

 let tableViewCellInterface = tableItem!.tableViewCellInterface() 

It calls this method (as one example):

 func tableViewCellInterface() -> JBSTableViewCellInterface { return JBSLiteratureTableViewCell.self as! JBSTableViewCellInterface } 

Returns a cell class, for example, "JBSLiteratureTableViewCell.self"

When I use the second protocol, the code looks like this and it does not compile:

 returnFloat = tableViewCellInterface.tableView(tableView, heightForRowAtIndexPath: indexPath, tableItem: tableItem!) 

It fails to compile due to the static keyword until earlier, and the compiler error that I get:

'JBSTableViewCellInterface' has no member named 'tableView'

If I remove static keywords from protocol functions, it compiles, but then subclasses of UITableViewCell complain, saying:

"JBSLiteratureTableViewCell" does not comply with the "JBSTableViewCellInterface" protocol

This is because they are now trying to make sure that instance methods exist, and this is not the case.

How to make a fast class conform to the protocol at the class level, so it can be my delegate, and not some kind of class instance? I'm sure I can get around this by creating JBSTableViewCellInterface helper protocol classes that are singleton and allow them to do the job, but I would prefer it directly to subclassing UITableViewCell in my class methods.

+6
source share
2 answers

UPDATED for Swift version 2.0 and higher

According to Greggo's answer, Swift 2.0+ allows you to define methods as static in the protocol definition. They must satisfy static / class methods in objects that implement the protocol.

You cannot satisfy the protocol definition for an instance method with a static method or vice versa, which makes this an incomplete answer to the question above.

If you want to try, just use the "static" keyword in the protocol definition for the methods that you will use as static or class methods in your respective objects:

 protocol InstanceVsStatic { func someInstanceFunc() static func someStaticFunc() } enum MyConformingEnum: InstanceVsStatic { case someCase static func someStaticFunc() { // code } func someInstanceFunc() { // code } } class MyConformingClass: InstanceVsStatic { class func someStaticFunc() { // code } func someInstanceFunc() { // code } } struct MyConformingStruct: InstanceVsStatic { static func someStaticFunc() { // code } func someInstanceFunc() { // code } } 

You can call the instance method with the static / class method:

This allows you to execute static code when you need to conform to a protocol that requires an instance method.

 struct MyConformingStruct: InstanceVsStatic { static func doStuffStatically(){ // code } static func someStaticFunc() { // code } func someInstanceFunc() { MyConformingStruct.doStuffStatically() } } 

Swift 1.2

Except indirectly, as indicated above, there is no way to use static (class) methods to comply with the protocol in pure version 1.2 and lower. This is a known bug / unrealized function: https://openradar.appspot.com/20119848

+5
source

If the func function is static, the developer should implement it as a static method, and if not, then as an instance method:

 protocol MixedProtocol { static func staticFoo() func instanceBar() } class ExampleClass : MixedProtocol { // implementing static func as class func is fine. // class funcs are overridable, not static ones class func staticFoo() { println( "I'm a class func" ) } func instanceBar() { println( "I'm an instance func" ) } } 

There is no direct way: compliance with the protocol means just that, and โ€œstaticโ€ is a very important feature of the announcement of a protocol participant, which developers must observe.

+2
source

Source: https://habr.com/ru/post/985398/


All Articles