Iglistkit: Protocol inheritance is not working with ListDiffable

Created on 16 Jun 2017  路  5Comments  路  Source: Instagram/IGListKit

New issue checklist

General information

  • IGListKit version: 3.0
  • iOS version(s): 10.3
  • CocoaPods version: 1.2.1
  • Xcode version: 8.3.2
  • Devices/Simulators affected:
  • Reproducible in the demo project? (Yes/No): Yes
  • Related issues:

Debug information

Here is an example of what I'm trying to do:

protocol ExampleProtocol: ListDiffable { 
   // ...
}

class ExampleClass: ExampleProtocol {
   // ...

  func diffIdentifier() -> NSObjectProtocol {
        return uuid as NSObjectProtocol
    }

    func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        guard self !== object else { return true }
        guard let object = object as? ExampleClass else { return false }
        return object.uuid == uuid

    }
}

Then here is the problem:

print(ExampleClass() is ListDiffable)

// Could not cast value of type 'Project.ExampleClass' (0x10182ad48) to 'IGListDiffable' (0x102444130).
question

Most helpful comment

Seems like this should work. I'd open an issue at http://bugs.swift.org

All 5 comments

Hm 馃

At first glance, seems to be a Swift and/or bridging bug -- not a ListKit bug.

@andreaantonioni -- what exactly are you trying to do? does this compile? what if you as! cast?

Yes, the example I wrote above compiles with this warning:

image

but then it crashes... Instead using as! as you suggested, it works:

let castedObject = ExampleClass() as! ListDiffable
print(castedObject is ListDiffable) // true

Here is an example of what I'm trying to do:


class ViewController: UIViewController {

    let models = [ListDiffable]()

    lazy var adapter: ListAdapter = {
        return ListAdapter(updater: ListAdapterUpdater(), viewController: self, workingRangeSize: 0)
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        models.appen(ExampleClass())
    }

}

extension ViewController: ListAdapterDataSource {

    public func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
        return models
    }

    public func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
        if object is ExampleClass() {
            return ExampleSectionController()
        }
        fatalError()
    }

    public func emptyView(for listAdapter: ListAdapter) -> UIView? {
        return nil
    }

}

extension ViewController: DelegateProtocol {

    func addObject(_ object: ExampleClass) {
        models.append(object)
        adapter.performUpdates(animated: false, completion: nil)
    }

}

And it breaks when I call adapter.performUpdates(animated: false, completion: nil)

@andreaantonioni is composing your class w/ both protocols, instead of just inheriting, an option? Not sure of your specific details, but composition seems like a more maintainable design to begin w/.

protocol ExampleProtocol: class { 
  // ...
}

class ExampleClass: ExampleProtocol, ListDiffable {

  func diffIdentifier() -> NSObjectProtocol {
    return uuid as NSObjectProtocol
  }

  func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
    guard self !== object else { return true }
    guard let object = object as? ExampleClass else { return false }
    return object.uuid == uuid
  }
}

Yep, It could be a solution. But I'm still asking to myself why is operator is not working, maybe @jessesquires is right and there's a bridging bug

Seems like this should work. I'd open an issue at http://bugs.swift.org

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jessesquires picture jessesquires  路  3Comments

kleiberjp picture kleiberjp  路  3Comments

PhilCai1993 picture PhilCai1993  路  3Comments

lucabartoletti picture lucabartoletti  路  3Comments

racer1988 picture racer1988  路  3Comments