2016-11-28 00:53:20 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > IGListDiffable and Equality Reference< / title >
< link rel = "stylesheet" type = "text/css" href = "css/jazzy.css" / >
< link rel = "stylesheet" type = "text/css" href = "css/highlight.css" / >
< meta charset = 'utf-8' >
< script src = "js/jquery.min.js" defer > < / script >
< script src = "js/jazzy.js" defer > < / script >
< / head >
< body >
< a title = "IGListDiffable and Equality Reference" > < / a >
< header >
< div class = "content-wrapper" >
< p > < a href = "index.html" > IGListKit Docs< / a > (100% documented)< / p >
< p class = "header-right" > < a href = "https://github.com/Instagram/IGListKit" > < img src = "img/gh.png" / > View on GitHub< / a > < / p >
< / div >
< / header >
< div class = "content-wrapper" >
< p id = "breadcrumbs" >
< a href = "index.html" > IGListKit Reference< / a >
< img id = "carat" src = "img/carat.png" / >
IGListDiffable and Equality Reference
< / p >
< / div >
< div class = "content-wrapper" >
< nav class = "sidebar" >
< ul class = "nav-groups" >
< li class = "nav-group-name" >
< a href = "Guides.html" > Guides< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "getting-started.html" > Getting Started< / a >
< / li >
< li class = "nav-group-task" >
< a href = "iglistdiffable-and-equality.html" > IGListDiffable and Equality< / a >
< / li >
2016-12-27 20:37:57 +00:00
< li class = "nav-group-task" >
< a href = "installation.html" > Installation< / a >
< / li >
2016-11-28 00:53:20 +00:00
< li class = "nav-group-task" >
< a href = "migration.html" > Migration< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Categories.html" > Categories< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Categories.html#/c:objc(cy)NSNumber@IGListDiffable" > NSNumber(IGListDiffable)< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Categories.html#/c:objc(cy)NSString@IGListDiffable" > NSString(IGListDiffable)< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Classes.html" > Classes< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Classes/IGListAdapter.html" > IGListAdapter< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListAdapterUpdater.html" > IGListAdapterUpdater< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListBatchUpdateData.html" > IGListBatchUpdateData< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes.html#/c:objc(cs)IGListCollectionView" > IGListCollectionView< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListGridCollectionViewLayout.html" > IGListGridCollectionViewLayout< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListIndexPathResult.html" > IGListIndexPathResult< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListIndexSetResult.html" > IGListIndexSetResult< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListMoveIndex.html" > IGListMoveIndex< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListMoveIndexPath.html" > IGListMoveIndexPath< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes.html#/c:objc(cs)IGListReloadDataUpdater" > IGListReloadDataUpdater< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListSectionController.html" > IGListSectionController< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListSingleSectionController.html" > IGListSingleSectionController< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListStackedSectionController.html" > IGListStackedSectionController< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Constants.html" > Constants< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Constants.html#/c:@IGListKitVersionNumber" > IGListKitVersionNumber< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Constants.html#/c:@IGListKitVersionString" > IGListKitVersionString< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Enums.html" > Enums< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Enums/IGListDiffOption.html" > IGListDiffOption< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Enums/IGListExperiment.html" > IGListExperiment< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Protocols.html" > Protocols< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterDataSource.html" > IGListAdapterDataSource< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterDelegate.html" > IGListAdapterDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterUpdaterDelegate.html" > IGListAdapterUpdaterDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListCollectionContext.html" > IGListCollectionContext< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListDisplayDelegate.html" > IGListDisplayDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListScrollDelegate.html" > IGListScrollDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListSectionType.html" > IGListSectionType< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListSingleSectionControllerDelegate.html" > IGListSingleSectionControllerDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListSupplementaryViewSource.html" > IGListSupplementaryViewSource< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListUpdatingDelegate.html" > IGListUpdatingDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListWorkingRangeDelegate.html" > IGListWorkingRangeDelegate< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Type Definitions.html" > Type Definitions< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListItemUpdateBlock" > IGListItemUpdateBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListObjectTransitionBlock" > IGListObjectTransitionBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListReloadUpdateBlock" > IGListReloadUpdateBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListSingleSectionController.h@T@IGListSingleSectionCellConfigureBlock" > IGListSingleSectionCellConfigureBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListSingleSectionController.h@T@IGListSingleSectionCellSizeBlock" > IGListSingleSectionCellSizeBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListAdapter.h@T@IGListUpdaterCompletion" > IGListUpdaterCompletion< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListUpdatingCompletion" > IGListUpdatingCompletion< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Functions.html" > Functions< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiff" > IGListDiff< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiffExperiment" > IGListDiffExperiment< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiffPaths" > IGListDiffPaths< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiffPathsExperiment" > IGListDiffPathsExperiment< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:IGListExperiments.h@F@IGListExperimentEnabled" > IGListExperimentEnabled< / a >
< / li >
< / ul >
< / li >
< / ul >
< / nav >
< article class = "main-content" >
< section >
< section class = "section" >
< a href = '#iglistdiffable-and-equality' class = 'anchor' aria-hidden = true > < span class = "header-anchor" > < / span > < / a > < h1 id = 'iglistdiffable-and-equality' > IGListDiffable and Equality< / h1 >
2016-12-01 02:03:57 +00:00
< p > This guide details how to write good < code > isEqual:< / code > methods. < / p >
< a href = '#background' class = 'anchor' aria-hidden = true > < span class = "header-anchor" > < / span > < / a > < h2 id = 'background' > Background< / h2 >
2016-11-28 00:53:20 +00:00
2016-12-01 02:03:57 +00:00
< p > < code > IGListKit< / code > requires that models implement the method < code > isEqualToDiffableObject:< / code > which should perform the same type of check as < code > isEqual:< / code > , but without impacting performance characteristics like in Objective-C containers such as < code > NSDictionary< / code > and < code > NSSet< / code > .< / p >
< a href = '#code-iglistdiffable-code-bare-minimum' class = 'anchor' aria-hidden = true > < span class = "header-anchor" > < / span > < / a > < h2 id = 'code-iglistdiffable-code-bare-minimum' > < code > IGListDiffable< / code > bare minimum< / h2 >
< p > The quickest way to get started with diffable models is use the < em > object itself< / em > as the identifier, and use the superclass’ s < code > -[NSObject isEqual:]< / code > implementation for equality:< / p >
2016-11-28 00:53:20 +00:00
< pre class = "highlight objective_c" > < code > < span class = "k" > -< / span > < span class = "p" > (< / span > < span class = "n" > id< / span > < span class = "o" > < < / span > < span class = "n" > NSObject< / span > < span class = "o" > > < / span > < span class = "p" > )< / span > < span class = "n" > diffIdentifier< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "n" > self< / span > < span class = "p" > ;< / span >
< span class = "p" > }< / span >
< span class = "o" > -< / span > < span class = "p" > (< / span > < span class = "n" > BOOL< / span > < span class = "p" > )< / span > < span class = "n" > isEqualToDiffableObject< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "n" > id< / span > < span class = "o" > < < / span > < span class = "n" > IGListDiffable< / span > < span class = "o" > > < / span > < span class = "p" > )< / span > < span class = "n" > object< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "p" > [< / span > < span class = "n" > self< / span > < span class = "nf" > isEqual< / span > < span class = "p" > :< / span > < span class = "n" > object< / span > < span class = "p" > ];< / span >
< span class = "p" > }< / span >
< / code > < / pre >
< a href = '#writing-better-equality-methods' class = 'anchor' aria-hidden = true > < span class = "header-anchor" > < / span > < / a > < h2 id = 'writing-better-equality-methods' > Writing better Equality methods< / h2 >
2016-12-01 02:03:57 +00:00
< p > Even though < code > IGListKit< / code > uses the method < code > isEqualToDiffableObject:< / code > , the concepts of writing a good equality check apply in general. Here are the basics to writing good < code > -isEqual:< / code > and < code > -hash< / code > functions. Note this is all Objective-C but applies to Swift also.< / p >
2016-11-28 00:53:20 +00:00
< ul >
2016-12-01 02:03:57 +00:00
< li > If you override < code > -isEqual:< / code > you < strong > must< / strong > override < code > -hash< / code > . Check out this < a href = "https://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html" > article by Mike Ash< / a > for details.< / li >
< li > Always compare the pointer first. This saves a lot of wasteful < code > objc_msgSend(...)< / code > calls and value comparisons if checking the same instance.< / li >
< li > When comparing object values, always check for < code > nil< / code > before < code > -isEqual:< / code > . For example, < code > [nil isEqual:nil]< / code > unintuitively returns < code > NO< / code > . Instead, do < code > left == right || [left isEqual:right]< / code > .< / li >
< li > Always compare the < strong > cheapest values first< / strong > . For example, doing < code > [self.array isEqual:other.array] & & self.intVal == other.array< / code > is extremely wasteful if the < code > intVal< / code > values are different. Use lazy evaluation!< / li >
2016-11-28 00:53:20 +00:00
< / ul >
< p > As an example, if I had a < code > User< / code > model with the following interface:< / p >
< pre class = "highlight objective_c" > < code > < span class = "k" > @interface< / span > < span class = "nc" > User< / span > < span class = "p" > :< / span > < span class = "nc" > NSObject< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > @property< / span > < span class = "n" > NSInteger< / span > < span class = "n" > identifier< / span > < span class = "p" > ;< / span >
2016-11-28 00:53:20 +00:00
< span class = "k" > @property< / span > < span class = "n" > NSString< / span > < span class = "o" > *< / span > < span class = "n" > name< / span > < span class = "p" > ;< / span >
< span class = "k" > @property< / span > < span class = "n" > NSArray< / span > < span class = "o" > *< / span > < span class = "n" > posts< / span > < span class = "p" > ;< / span >
2016-12-01 02:03:57 +00:00
2016-11-28 00:53:20 +00:00
< span class = "k" > @end< / span >
< / code > < / pre >
< p > You would implement its equality methods like so:< / p >
< pre class = "highlight objective_c" > < code > < span class = "k" > @implementation< / span > < span class = "nc" > User< / span >
< span class = "k" > -< / span > < span class = "p" > (< / span > < span class = "n" > NSUInteger< / span > < span class = "p" > )< / span > < span class = "n" > hash< / span > < span class = "p" > {< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > return< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > identifier< / span > < span class = "p" > ;< / span >
2016-11-28 00:53:20 +00:00
< span class = "p" > }< / span >
< span class = "o" > -< / span > < span class = "p" > (< / span > < span class = "n" > BOOL< / span > < span class = "p" > )< / span > < span class = "n" > isEqual< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "n" > id< / span > < span class = "p" > )< / span > < span class = "n" > object< / span > < span class = "p" > {< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "n" > self< / span > < span class = "o" > ==< / span > < span class = "n" > object< / span > < span class = "p" > )< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "nb" > YES< / span > < span class = "p" > ;< / span >
< span class = "p" > }< / span >
< span class = "k" > if< / span > < span class = "p" > (< / span > < span class = "o" > !< / span > < span class = "p" > [< / span > < span class = "n" > object< / span > < span class = "nf" > isKindOfClass< / span > < span class = "p" > :[< / span > < span class = "n" > User< / span > < span class = "nf" > class< / span > < span class = "p" > ]])< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "nb" > NO< / span > < span class = "p" > ;< / span >
< span class = "p" > }< / span >
2016-11-28 00:53:20 +00:00
< span class = "n" > User< / span > < span class = "o" > *< / span > < span class = "n" > right< / span > < span class = "o" > =< / span > < span class = "n" > object< / span > < span class = "p" > ;< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > return< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > identifier< / span > < span class = "o" > ==< / span > < span class = "n" > right< / span > < span class = "p" > .< / span > < span class = "n" > identifier< / span >
< span class = "o" > & & < / span > < span class = "p" > (< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > name< / span > < span class = "o" > ==< / span > < span class = "n" > right< / span > < span class = "p" > .< / span > < span class = "n" > name< / span > < span class = "o" > ||< / span > < span class = "p" > [< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > name< / span > < span class = "nf" > isEqual< / span > < span class = "p" > :< / span > < span class = "n" > right< / span > < span class = "p" > .< / span > < span class = "n" > name< / span > < span class = "p" > ])< / span >
< span class = "o" > & & < / span > < span class = "p" > (< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > posts< / span > < span class = "o" > ==< / span > < span class = "n" > right< / span > < span class = "p" > .< / span > < span class = "n" > posts< / span > < span class = "o" > ||< / span > < span class = "p" > [< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > posts< / span > < span class = "nf" > isEqualToArray< / span > < span class = "p" > :< / span > < span class = "n" > right< / span > < span class = "p" > .< / span > < span class = "n" > posts< / span > < span class = "p" > ]);< / span >
2016-11-28 00:53:20 +00:00
< span class = "p" > }< / span >
< span class = "k" > @end< / span >
< / code > < / pre >
2016-12-01 02:03:57 +00:00
< a href = '#using-both-code-iglistdiffable-code-and-code-isequal-code' class = 'anchor' aria-hidden = true > < span class = "header-anchor" > < / span > < / a > < h2 id = 'using-both-code-iglistdiffable-code-and-code-isequal-code' > Using both < code > IGListDiffable< / code > and < code > -isEqual:< / code > < / h2 >
< p > Making your objects work universally with Objective-C containers and < code > IGListKit< / code > is easy once you’ ve implemented < code > isEqual:< / code > and < code > -hash< / code > .< / p >
< pre class = "highlight objective_c" > < code > < span class = "k" > @interface< / span > < span class = "nc" > User< / span > < span class = "o" > < < / span > < span class = "n" > IGListDiffable< / span > < span class = "o" > > < / span >
2016-11-28 00:53:20 +00:00
2016-12-01 02:03:57 +00:00
< span class = "c1" > // properties...
< / span >
2016-11-28 00:53:20 +00:00
< span class = "k" > @end< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > @implementation< / span > < span class = "nc" > User< / span >
2016-11-28 00:53:20 +00:00
< span class = "k" > -< / span > < span class = "p" > (< / span > < span class = "n" > id< / span > < span class = "o" > < < / span > < span class = "n" > NSObject< / span > < span class = "o" > > < / span > < span class = "p" > )< / span > < span class = "n" > diffIdentifier< / span > < span class = "p" > {< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > return< / span > < span class = "err" > @< / span > < span class = "p" > (< / span > < span class = "n" > self< / span > < span class = "p" > .< / span > < span class = "n" > identifier< / span > < span class = "p" > );< / span >
2016-11-28 00:53:20 +00:00
< span class = "p" > }< / span >
< span class = "o" > -< / span > < span class = "p" > (< / span > < span class = "n" > BOOL< / span > < span class = "p" > )< / span > < span class = "n" > isEqualToDiffableObject< / span > < span class = "o" > :< / span > < span class = "p" > (< / span > < span class = "n" > id< / span > < span class = "o" > < < / span > < span class = "n" > IGListDiffable< / span > < span class = "o" > > < / span > < span class = "p" > )< / span > < span class = "n" > object< / span > < span class = "p" > {< / span >
2016-12-01 02:03:57 +00:00
< span class = "k" > return< / span > < span class = "p" > [< / span > < span class = "n" > self< / span > < span class = "nf" > isEqual< / span > < span class = "p" > :< / span > < span class = "n" > object< / span > < span class = "p" > ];< / span >
2016-11-28 00:53:20 +00:00
< span class = "p" > }< / span >
< span class = "k" > @end< / span >
< / code > < / pre >
< / section >
< / section >
< section id = "footer" >
2017-01-04 18:09:57 +00:00
< p > © 2017 < a class = "link" href = "https://twitter.com/fbOpenSource" target = "_blank" rel = "external" > Instagram< / a > . All rights reserved. (Last updated: 2017-01-04)< / p >
2016-12-08 18:03:33 +00:00
< p > Generated by < a class = "link" href = "https://github.com/realm/jazzy" target = "_blank" rel = "external" > jazzy ♪♫ v0.7.3< / a > , a < a class = "link" href = "http://realm.io" target = "_blank" rel = "external" > Realm< / a > project.< / p >
2016-11-28 00:53:20 +00:00
< / section >
< / article >
< / div >
< / body >
< / div >
< / html >