I'm trying to write a method that compares 2 objects. The problem I have is: how do I know if a property of a primitive type?
+(BOOL)isObject:(void*)object1 equalTo:(void*)object2
{
if (object1 == nil && object2 == nil)
return TRUE;
if ((object1 != nil && object2 == nil) ||
(object1 == nil && object2 != nil) ||
([object1 class] != [object2 class]))
return FALSE;
if (object1 != object2)
{
u_int count;
Ivar* ivars = class_copyIvarList([object1 class], &count);
for (int i=0; i < count; i++)
{
id v1 = object_getIvar(object1, ivars[i]);
id v2 = object_getIvar(object2, ivars[i]);
if (![ObjectComparer isObject:v1 equalTo:v2])
return FALSE;
}
}
return TRUE;
}
That will work for objects but fail for primitive types. Another thing is I want to pass parameters as something general such as id but does not work for primitives. At least i need to know that it is a primitive type and convert it into id.
Any ideas?
Answering strictly on properties (as in class_copyPropertyList
), not on instance variables (as per your current code's class_copyIvarList
)...
People usually dodge around the issue by using key-value coding. If you use valueForKey:
then the runtime automatically promotes primitives to object types.
If you were to implement that at the Objective-C level you'd get the NSMethodSignature
using -methodSignatureForSelector:
and check the methodReturnType
property, which is in the standard Objective-C type encoding form (ie, to match @encode
).
Working directly with the C runtime, I imagine you'd use method_copyReturnType
on the getter.
As for instance variables, I'm not sure there's a way to query their type.
Note also that the normal way of handling this is to have objects themselves implement isEqual:
. It's part of NSObject
so guaranteed always to be defined. Classes themselves should implement the logic they need to perform comparison by value.