How to get pointer to an existing NSObject during runtime using its hash value - ios

Assuming I have a hash value of some NSObject during runtime.
Is there a way to find a pointer to that object using just hash value?
I don't want to store pointers to objects and their hashes as keys. I imagine that iOS already doas that.

There is no way, not even an unreliable way, to do this.
Many objects have hashes in ways that makes it impossible to reference it. You will have duplicates because of this. One example, as #Martin said, is NSArrays. NSArrays' hashes are just the number of elements in the array.

Related

iOS Dictionary Response by added objects [duplicate]

I've run into the same problem as found in this question. However, I have a follow-up question. I seem to be in the same situation as the original asker: I have a plist with a hierarchy of dictionaries that define a configuration screen. These are not mutable and will stay the same throughout the application. Since the original discussion seems to focus on problems arising from mutating the dictionary, I must ask for comfirmation: is the order of a dictionary guaranteed the same as they are in the plist, i.e. as it is read (with initWithContentsOfFile)? Can I use allKeys on it in this case to get a correct-order array of keys if the dictionary never changes?
No, the keys are not likely to appear in the same order as your plist file. I can't look under the hood, but I would guess that the keys are ordered in whatever way that provides an efficient look-up. The documentation for allKeys says that the order of the elements in the array is not defined.
If you need an NSDictionary that maintains order, take a look at CHDataStructure's CHOrderedDictionary, which does exactly that. I use it all the time.
I would not assume that the keys will be in any kind of order because allKeys does not guarantee order.
Internally, NSDictionary uses a hash table.
From allKeys description:
The order of the elements in the array
is not defined.
If you want to display values in some order then get the keys, sort the keys array and then get the value for each key.
Nothing at all is guaranteed about order. It’s not even guaranteed that iterating over a dictionary twice will give you the keys in the same order.

Are dictionaries the presumed collection (array) in Xcode?

To use uisearchdisplaycontroller to specify a search on specific array fields, I found that the syntax caters only to key-value (dictionary?) data. Now, when I need to sort an array, I see again that the methods cater to key references, not mere array indexing. (I've built complex data with keyless arrays, not dictionaries.) Do I understand correctly that I should default to using dictionaries everywhere? Is there any situation to use plain arrays?
I see now the Key-Value Coding Guide (document 1812 of 3894)... should get to it any minute now.
It is NOT mandatory but it will be much comfortable when using NSDictionary.
Also, with the plain array, you can sort it as well without using "%K" at predicate format or using block comparator

Best way to represent un-ordered data in a plist

I'm making a plist to hold genre synonyms. The list of synonyms for a given genre doesn't have any inherent order to it.
Should I use an array (which implies an order that doesn't exist) or a dictionary (which implies there's a corresponding value for each key, which doesn't exist).
Simply put--to store an unordered set in a plist, how should I represent it and why?
(To clarify: If there were a Set data structure in the plist editor, I would use that, but I only have Array and Dictionary to choose from.)
More details: I'm going to be looking up by the primary representation of the genre, thus the outer data structure in the plist has to be a dictionary.
But then for the synonyms, the only operation necessary is to enumerate them using a block.
So either an array or a dictionary will do. However, I'm concerned that using an array will imply an order that doesn't have any semantic meaning. On the other hand, is it a common occurrence to have dictionaries in plists that don't have a corresponding value?
Editing again to respond to Josh's comments:
I like your idea of converting into an NSSet after reading in the plist. However, I could still do that with a dictionary, right? So not sure why an array is the obvious choice.
If someone else edits the plist, they might think there's a meaning to the order, when in reality, the ordering is arbitrary.
Surprised no-one has defended using a dictionary instead of an array. Is there a reason a dictionary shouldn't be used in a plist for this purpose?
If you don't care about order, then the arbitrary order you get from building an array is equivalent to the arbitrary order you'd get by using a set. You can also very easily convert an array in a plist to an NSSet after reading it back: +[NSSet setWithArray:]
So use an array.
I would just use an array, since you say there's no corresponding key for a dictionary entry.
At the same time, if you're typing in a large number of entries into plist files (www), your fingers may get tired from dealing with the raw XML or plist editor stuff. You might want to consider a different way to save your synonyms?
Use an NSArray if lookup by item is not needed. If lookup is needed use an NSDictionary.

How NSSet make sure the uniqueness of it objects?

I want to know how NSSet make sure that it has only unique objects? When we try to add duplicate value, then on which criteria it decides that it has already this value? I want to know the underlying uniqueness criteria.
NSSet uses your object's implementation of isEqual: method to decide object equality. It also uses hash to make the lookup much faster.
-(BOOL)isEqual:(id)other;
-(NSUInteger)hash;
When two objects are equal, their hash methods must return the same value (objects with the same hash, however, may not necessarily be equal to each other).
When your hash and isEqual: are implemented properly, NSSet can decide the equality by checking only a handful of objects whose hash "collides" with the hash of the object you are adding to the set.
take a look at Object Comparison in the official apple documentation. As you can see there most of the containers use hash to compare objects.
I want to know how NSSet make sure that it has only unique objects
Whenever you try to add object it will check for hash value of all other existing objects inside of it. Based on that it will keep it as unique
If two objects are equal, they must have the same hash value
When we try to add duplicate value, then on which criteria it decides that it has already this value?
if the new object hash value matches the existing then it will be considered as dublicate
Refer this Apple's documentation
First of all the set checks hash values of objects. If hashes are not equal it means that objects are guaranteed to be different. If hashes are equal it however doesn't mean that objects are neccessarily equal, so the set has to make sure and check their isEqual: methods

Mutable array comparison for copied objects

I am trying to do array comparison on 2 mutable arrays. In one of the array, i am storing my model objects and in the other array I am storing a copy of the model objects using [myObject copy]. My model object is a subclass of NSObject so I have added the copyWithZone: method as well. However when I do array compare using isEqualToArray on these two arrays it always returns false. Will the compare not work on copied objects? Or am I going wrong somewhere else?
P.S: As an overview, what I'm trying to do is to check whether something is changed in my model before calling an update service. I want to call the service Only if any of the model objects have changed.
Will the compare not work on copied objects?
You can very easily find out the answer to this question by just copying a single object and checking for equality agains the original.
SPOILER
The results you are going to see will depend on if you have implemented custom hash and isEqual: methods in your class. Without those it will default to the superclasses implementation (NSObject) which considers equality to be the same pointer. Since a copy is a new pointer to the same object, NSObject won't consider them equal.
I would recommend that you read about object equality in this NSHipster article (great to start with) and/or in this article by Mike Ash (if you are feeling curious)
Method isEqualToArray acts as follows. It takes one by one the next objects from two arrays and compare them using isEqual. The latter compares hash (NSInteger property) of NSObjects (or its subclasses).
In general it is the address of the object. hash can be redefined while subclassing but it may cause big problems.
For copied objects you will have different hashes. And thus isEqualToArray is always FALSE.
But if you use simple data classes like NSNumber, NSString as elements to compare, you will get TRUE under copying them.

Resources