2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【swift】RxDataSourcesでEquatableに準拠せさるときに!

Last updated at Posted at 2018-07-23

はじめに

RxSwiftで、TableViewの差分更新を行うときに、RxDataSourcesを使うことがあると思います。
RxDataSorcesの詳細に関しては、公式レポジトリーを参照してださい....

RxDataSources

RxTableViewSectionedAnimatedDataSourceを使う場合、AnimatableSectionModelTypeに準拠したmodelを用意する必要があります。
実装としては

  1. RxTableViewSectionedAnimatedDataSourcecellsectionなどのtableViewの設定をAnimatableSectionModelTypeに準拠したmodelを用いて行う
  2. AnimatableSectionModelTypeに準拠したObservablemodeltableViewbindする

詳細はサンプルコードをみてください。(RxDataSources/Example/Example1_CustomizationUsingTableViewDelegate.swift

Equatableへの準拠

上記の実装のように、RxDataSourcesを使うにはAnimatableSectionModelTypeに準拠したmodelを用意する必要があり、準拠するAnimatableSectionModelTypeのprotocolは下記のようになっています。

AnimatableSectionModelType.swift
public protocol AnimatableSectionModelType {
    : SectionModelType
    , IdentifiableType where Item: IdentifiableType, Item: Equatable {
}

また、AnimatableSectionModelTypeが準拠しているSectionModelTypeは下記の実装になっています。

SectionModelType.swift
public protocol SectionModelType {
    associatedtype Item

    var items: [Item] { get }

    init(original: Self, items: [Item])
}

SectionModelTypeのGenericsのItemIdentifiableTypeEquatableに準拠する必要があります!!

困ったこと:Equatableに準拠できない!?

NSObjectに準拠したmodelをEquatableに準拠させようとしていた。。。

sample.swift
class TestModel: NSObject { 
    let id: Int
}

extension TestModel: Equatable {
    static func == (lhs: TestModel, rhs: TestModel) -> Bool {
        return lhs.id == rhs.id
    }
}

下記のコンパイルエラーがでる
Redundant conformance of 'TestModel' to protocol 'Equatable'

自作したクラスTestModelEquatableに準拠したつもりはないのに、なぜ準拠済みなのかわからない??

理由:NSObjectがすでにEquatableである!

NSObjectのドキュメントのConformsにあるように、NSObjectはすでにEquatableに準拠しています。そのため、上記の実装だと既に準拠だとエラーが出ます。
ちなみに、NSObjectEquatableは参照しているポインタが同じかどうかをチェックしています。

superクラスの比較でなく、subclassを用いて比較させたい場合は、subclassにクラスメソッドを実装することで、subclassでの比較を行うことができます。

extension TestModel {
    static func ==(lhs: TestModel, rhs: TestModel) -> Bool {
        return lhs.id == rhs.id
    }
}

swift4.1からのEquatable

ここからは上記のエラーとは異なりますが、Equatableなクラスを実装するときの追加の話です。
swift4.1からは、より簡単にEquatableの実装を行うことができます。

swift4.1で実装されたSynthesizing Equatable and Hashable conformanceによって、コンパイラーが自動的にEquatableHashableに準拠させてくれます。

条件としては、
Equatableの実装するクラス or enum or structで定義されているstored instance propertyassociated valueが、Equatableに準拠している場合に、static func == (lhs: Self, rhs: Self) -> Boolが暗黙的に実装されます。

実装例が下記になります!
swift4.0の場合

test.swift
struct Person: Equatable {
    let firstName: String
    let lastName: String
    
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.firstName == rhs.firstName &&
               lhs.lastName == rhs.lastName &&
    }
}

swift4.1の場合(暗黙的にEquatableに準拠できる!!)

test.swift
struct Person: Equatable {
    let firstName: String
    let lastName: String
}

上記のようにEquatableに準拠する際に、大量のコードを記述する必要がなくなって、よりEquatableが使いやすくなり、RxDataSourcesも使いやすくなったと思います!!!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?