UICollectionViewDiffableDataSource - Crash when having equal items with different hash - swift

I am using UICollectionViewDiffableDataSource to fill UICollectionView with data. My understanding is that DiffableDataSource compares items by using == and then if items are equal it compares hash values to see if something changed.
But according to the error I am getting this isn't the case.
Diffable data source detected item identifiers that are equal but have different hash values. Two identifiers which compare as equal must return the same hash value. You must fix this in the Hashable (Swift) or hash property (Objective-C) implementation for the type of these identifiers
In my case I have item that I compare against uniqueID and hashValue is determined by value that user entered. What is the point of using == and hashValue if they can't be different?

Related

Suggestion about keeping a track of fields

I am posting this message to get a suggestion about the best approach.
I am making a program in which users select the fields that they want to use. The list appears in the form of a table on the next screen. Depending on the chosen fields, the placeHolder in the textFields change. Therefore, I have to keep a track of selected fields.
I have considered the following approaches so far:
Two arrays. One stores the list of the labels on the cell and the second array stores 1/0 values. 1: field is selected, 0: not selected. Therefore I will have to obtain the name of the field from array 1 and whether it is selected or not from the second one.
One array containing the 1/0 indicating whether the field is selected or not. I traverse the array to determine whether which placeHolders should be shown.
NSDictionary: It will contain object:"name of the fields" and key:1 or 0.
I don't find either of these options as good programming practice because there are lot of if and else statements and plus, there is a tremendous amount of repetition in the code.
Can you please suggest the best way to approach this problem?
Thanks!
Not sure why you think there are a lot of if/else statements. You can do it with an array of dictionaries, where each dictionary contains two keys: field name and selected. Fieldname is NSString, selected is NSNumber wrapping a boolean value. Then in your cellForRowAtIndexPath you have something like:
NSDictionary *cellData = dataArray[indexPath.row];
cell.textLabel.text = cellData[#"field_name"];
if ([[cellData#["selected"] boolValue] == YES) { ... do whatever you do when the cell is selected, like add a checkmark ... }
You might also think about making a custom data class to hold each cell's data. You can create properties for the label name and the selected-ness (this will avoid having to wrap and unwrap NSNumbers to represent YES/NO). You could define methods on the custom class that return the correct label depending on the selected-ness. Then you just create an array of these custom objects.
I guess what you want is to figure out which one has been selected. You can use a number to mark up which one is selected.
Let's say there is 3 fields: field0 field1 field2 and a number in binary 000. Once field1 is selected, then mark the number as 010. Pass this number to the next screen, then you can use & for every filed.
For field0, you may do 010 & 000 and get a result 0 which means field0 is not selected.
For field1, you may do 010 & 010 and get a result no 0 which manes field1 is selected.
For field2, you may do 010 & 100 and get a result 0 which manes field2 is not selected.

UITableView Section Indexing

I'm creating a tableview with an index, my index array has 26 values (A-Z) but my data source may only have a few sections (A,D,S).
My challenge is that the user selects an index value but the incorrect section should not display, if I'm not mistaken this is due to the index value returned is different to the selected value for row.
In my example above selecting index 'D' will return a value of 3, but the section value for 'D' in my data source is 1. Is this normal, if it is hows the best way to handle this?
Thanks
I believe that this is the correct behavior. Solution would be to create your index with only the values that actually contain data.
When more data is added, add new sections if required.

How do I watch for changes made in NSMutableArray or NSMutableDictionary?

I've noticed that the method 'hashcode' for both NSMutableDictionary and NSMutableArray is giving me the hashvalue to be the number of keys irrespective of the value for NSMutableDictionary and number of objects in case of NSMutableArray.
Basically, I want to detect the change in NSMutableDictionary. My dictionary contains key/value pairs as string/NSMutableArray. And I'want to detect the change in dictionary if an item is added/deleted from any of its values.
In case if I go for calculating hash for NSMutableArray which are the values in my dictionary, it's not feasible since there's also a possibility of a different value added and existing deleted in which case simply giving me the number of items are going to remain same but the hash should be different.
Which is the best way to handle such change in dictionary?
You can retain the original dictionary an test if it is equal to the new one
isEqualToDictionary:
Returns a Boolean
value that indicates whether the
contents of the receiving dictionary
are equal to the contents of another
given dictionary.
- (BOOL)isEqualToDictionary:(NSDictionary*)otherDictionary
Docs here

Objective-C, I'm having some problems with arrays and dictionaries atrting at zero or not?

I'm using a dictionary and an array to store the section title for a table view, along with the number of rows in each. I'm adding to the array and the dictionary in a loop of the records from my database in mu populateDataSource method.
I've got two dates from three records in my database. 2010-11-05 and 2010-11-07
I'm not sure if its because the table view events need to start at zero and the dictionary / array start at one ?
Or maybe my sectionTitles addObject, is added values each time, rather than adding unique dates. If so how i can search or only allow unique values ?
Any ideas ?
Arrays have a starting index of 0, but dictionaries don't essentially work that way. What is the purpose of the dictionary in this case? To get an object from the dictionary you give it a key. If you're going through a loop and not getting the expected result, maybe the dictionary isn't getting the key that it should be.

NSMutableSet vs NSMutableArray

What's the difference?
In my context, I need to be able to dynamically add to and remove objects. The user clicks on rows of a table that check on and off and thus add or remove the referenced object from the list.
A wild guess is that array has indexed items while set has no indexes?
An NSSet/NSMutableSet doesn't keep items in any particular order. An NSArray/NSMutableArray does store the items in a particular order. If you're building a table view, you should definitely use an array as your data source of choice.
Also, NSMutableSet makes sure that all objects are unique.
NSMutableArray goes well with UITableView since elements have index, so you can return [array count] to get number of table rows, or [array objectAtIndex:rowNumber] to easily associate element with row.
Also, according to the documentation, testing for object membership is faster with NSSets.
You can use sets as an alternative to arrays when the order of
elements isn’t important and performance in testing whether an object
is contained in the set is a consideration—while arrays are ordered,
testing for membership is slower than with sets.
Well there are 3 main differences. 1) Sets are unordered 2)Don't have an index & 3)Cannot have duplicate values where Arrays are ordered, indexed & can store duplicate values.