Swift 3: Is there a way to apply an object to a class and protocol at the same time?

I have read the relevant sections of Apple Swift iBook (Type Casting and Protocols), but I can find a way to indicate that the object is an instance of a particular class that conforms to a specific protocol.

As an example, in tableView(_: , cellForRowAt: )I would like to pass a cell returned tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath)as a subclass UITableViewCellthat conforms to the protocol RLMEntityCapableCell(Just indicates that the conformers have a variable named itemthis instance Object, or one of its subclasses).

This route works, but double casting seems excessive:

protocol RLMEntityCapableCell: class  {
     var item: Object { get set }
}

 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as! RLMEntityCapableCell // Cast here so we can set item
    cell.item = items[indexPath.row]
    return cell as! UITableViewCell // Cast again so the return type is right…
}

This other approach:

var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) 
           as! RLMEntityCapableCell, UITableViewCell

gives this error:

missing template

it’s so clear that this is not the right way to do this.

, UITableViewCell UICollectionViewCell, .

Edit:

, Realm, , Array Dictionary. , , , , , UITableViewCell, RLMEntityCapableCell. , , , ( Object), , .

+6
2

, ... .

Swift ( 4) , ,

, Swift , .

&, AnyObject, (, SomeClass & SomeProtocol).

:

var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) 
           as! UITableViewCell & RLMEntityCapableCell

, , , RLMEntityCapableCell ( ). Swift 5 :)


, Class Subtype Existentials (Swift 4):

protocol P {}
struct S {}
class C {}
class D : P {}
class E : C, P {}

let u: S & P // Compiler error: S is not of class type
let v: C & P = D() // Compiler error: D is not a subtype of C
let w: C & P = E() // Compiles successfully

protocol P {}
class C {}
class D : C { }
class E : C { }
class F : D, P { }

let t: C & D & P = F() // Okay: F is a subclass of D and conforms to P
let u: D & P = t       // Okay: D & P is equivalent to C & D & P
let v: C & D & P = u   // Okay: C & D & P is equivalent to D & P
let w: D & E & P       // Compiler error: D is not a subclass of E or vice-versa
+2

UITableViewCell item, , , , , cell .

protocol RLMEntityCapableCell: class  {
    var item: Object { get set }
}

class RLMCell: UITableViewCell, RLMEntityCapableCell {
    var item: Object
}

 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: reuseID, for: indexPath) as? RLMCell ?? RLMCell() 
    cell.item = items[indexPath.row]
    return cell
}

:
1. dequeueReusableCell , .
2. : item , .

-1

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


All Articles