I need to store a bunch of objects in an NSOrderedSet object.
Unfortunately, I don't want the set to perform any sort of equality checking on anything other than the object pointer itself.
It appears as though some objects (such as NSNumber) override isEqual: and perform internal value comparison, which means that two NSNumber instances with the same value (but different object pointers) cannot be stored in the same ordered set.
How can I work around this issue?
It has occurred to me that I could just store the object pointer itself as an NSValue or NSString object (using #"%p") instead.
However this means that I need to wrap all calls to containsObject: and indexOfObject: and create a new NSValue or NSString object every time I want to query the set.
Is there any better way of handling this?
I would like to check if my NSMutableArray contains my custom object. But if I understand correct contains functions searches for the same object in array (placed at the same memory point)
if(![objectArray containsObject:objToCheck])
{
[objectArray addObject:objToCheck];
}
I know that objectArray has identical object with identical variable values compared to objToCheck, yet such if always returns false. Is there a way to check this without writing custom loop and comparing objects by their parameters?
Override the [NSObject isEqual:] method (actually it's part of the NSObject protocol) of your custom object and check whatever instance variables make sense to you for an object to be considered equal.
Here's an Apple Cocoa Competency article on the subject.
You might try creating a temporary NSSet from your array and testing against that for membership.
why would you use #property with NSArray?
The reason for my question is because I was under the impression that #properties were mainly used to take advantage of the getter and setter you get for free when you use #property, but when you assign an NSArray to a property you know you will never use the getter and setter to access the objects in the array, why use properties on this case. Does this have to do with ARC, in other words is this considered a better memory management practice?
You use a property to get or set the whole array. You also use the property to access individual elements of the array.
Using a property with an array has nothing to do with ARC or MRC. Properties are a way to encapsulate data. That's it.
If you don't wish to provide access to the whole array then don't use a property. Add method(s) to set/get individual elements of the internal array if that is appropriate.
Along with what already said by other answers, I usually like to copy my array for security purposes.
If you're accepting an NSArray by the client, she could potentially provide you a NSMutableArray instance. If that's the case and you want to ensure that the array you're working with doesn't change unexpectedly, you'd better copy it as opposed to retain it.
Properties come in handy in this case since you can declare
#property (nonatomic, copy) NSArray * myArray;
and be sure that you're the only owner of that array after you assigned it.
I typically use this strategy for any class with mutable subclasses, such as NSString, NSArray, NSSet and so on, whenever I care about the ownership of the data.
The downside of this strategy is of course memory efficiency, but in the end engineering is the art of intelligent compromise.
To use the array outside of a single method or class. ClassA.array = ClassB.array; or to simply read from the array in a different method of the same class since the array will dealloc immediately after execution.
but when you assign an NSArray to a property you know you will never
use the getter and setter to access the objects in the array, why use
properties on this case.
For the same reasons that you use properties for other objects:
accessors: The accessors are for the array itself, not objects in the array. It's not uncommon to get or set an entire array at once:
NSArray *kids = frank.children; // get the array
mary.children = #[#"Nick", #"Sam", #"Susan"]; // set the array
abstraction: Using properties instead of accessing the underlying array directly makes it easier to change the implementation later, should that become necessary.
KVC compliance: You get it for free with properties. With collections like arrays, KVC gives you a lot of power. You can use collection operators like #avg and #max as well as indexed accessors:
int employees = [accounting countOfEmployees]; // same as [accounting.employees count]
Employee *thirdEmployee = [engineering objectInEmployeesAtIndex:2]; // same as [engineering.employees objectAtIndex:2]
I have NSArray and I want to remove duplicates from it. I know that using this method
[NSSet setWithArray:[arrAllValues valueForKey:#"value"]]
I also know that it invokes method specified in valueForKey parameter. But I don't know what method NSSet invokes to compare objects in array.
My problem is that I want to compare property named "value", but I want to return array of the object that contains the property and not the property. Can I do that?
Thanks !!!
It compares them using the NSObject protocol reference method:
- (BOOL)isEqual:(id)anObject
therefore, you can override this method in your class to implement the desired behavior, as a note just like you would do it in Java, you should also override hash.
I have an array of Person objects (which has a number of attributes). I want to make another array with just the Person's "fullname" attribute. Is there a simple way to do this, other than the obvious one: iterate over the original array, and copy over the fullname one-by-one into another array? Can we do this initWithArray: and tell it to use the object's fullname property when copying?
NSArray indeed has built-in method for that:
NSArray *nameArray = [personArray valueForKey:#"fullname"];