On 15.12.2012, at 01:44, Uli Kusterer wrote:

> 
> On 15.12.2012, at 01:38, Uli Kusterer <witness.of.teacht...@gmx.net> wrote:
> 
>> On 12.12.2012, at 10:03, Andreas Grosam <agro...@onlinehome.de> wrote:
>>> How can I check at runtime whether an object (id) is actually a block, and 
>>> not another kind of object?
>> 
>> Not a good idea. What are you really trying to do?
(I explained this in more detail in later posts, see also below)

>> Here's a few common cases and suggestions on how to do it better, and why:
>> 
>> 1) Serializing objects. Generally, the object (or a category on it if it's 
>> an object you didn't create) should implement a method that knows how to 
>> serialize/unserialize it, like -initWithCoder: and -encodeWithCoder:. This 
>> allows any class to be added, and allows for overriding a the method in a 
>> subclass. If you use -isKindOfClass:

>> , all subclasses will also return YES, and that one method will have to know 
>> about all the different types (from different layers of your app that might 
>> be serialized), and you'll have one file with thousands of dependencies, 
>> that get dragged into any other app that wants to be able to use the same 
>> serialization mechanism.
>> 
>> 2) Implementing special behaviour on some objects, while falling back on 
>> some default behaviour for all others. Call respondsToSelector: in this 
>> case. It has the advantage that it doesn't break duck typing. Even if you 
>> get an NSProxy for the actual object, it will respond to the selector and 
>> still work as expected. 
> 
> Same for any other kind of method forwarding or dynamic method implementation 
> like Key-Value-Observing.

I agree, and I understand the point. However, this won't help in *my* case. I 
cannot easily implement a category method for a class, since these objects 
don't know how to perform those actions required by the client. The kind of 
action performed depends on the "traits" (say, whether it is an associative 
container, an array of objects, a character representation, or a sequence of 
bytes, etc.) of the objects **and** the "context":

RXTraits* traits = [obj rx_traits];  // same as [[obj class] rx_traits];
if (traits.isAssociativeContainer) {
    [obj enumerateKeysAndObjectsUsingBLock: /* do something depending on 
context */ ];
}
else if (traits.isOrderedSequence) {
    [obj enumerateObjectsAtIndexesUsingBlock: /* do something depending on 
context */ ];
}
...

Passing the context through a category method would be possible, but this would 
result in many duplications of code - which is also a code smell ;)

Using the "traits" concept, isn't for free as well, though.


> 
>> Asking for an object's class using isKindOfClass: is a definite code smell.

I wouldn't say that this is always the case. But most often I don't want to 
know the kind of class, but some more abstract "concept". So, asking the class 
is probably not what I want. Rather I want to know whether the object fulfills 
some promises or exhibits some behavior (the duck, you know). Then I agree, it 
is likely something that smells.



Andreas
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to