NSLog(@"%@",[NSProxy class]);

  • I have come across a difficulty with an NSProxy subclass on 10.3.9
    which can be summed up with the following lines:

    Class p=[NSProxy class];
    NSLog(@"class %@",p);

    The second line throws an exception:
    *** Uncaught exception: <NSInvalidArgumentException> *** -[NSProxy
    methodSignatureForSelector:] called!

    If "NSProxy" above is any NSObject subclass, then it prints the class
    name as expected.

    The reason this occurs is because +[NSProxy class] does not implement
    the proper description method. Apparently, not all meta-classes are
    created equal.

    -----
    Workarounds are:
    1) NSLog(@"class %@",NSStringFromClass([NSProxy class]));
    or
    2)
    @implementation NSProxy (Desc)
    +(NSString*)_copyDescription //yes, this is a private method
    {
    return [NSStringFromClass([self class]) copy]; //extra retain
    increment is critical here
    }
    @end

    I found solution (2) by adding a category on NSProxy:
    -(NSMethodSignature*)methodSignatureForSelector:(SEL)sel
    {
    NSLog(@"selector! %@",NSStringFromSelector(sel));
    return nil;
    }

    Because NSProxy is a stripped down root object, perhaps this is how
    things are supposed to behave; but I hope this will help anyone who
    comes across this in the future.

    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
    AgentM
    <agentm...>
    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
  • Agent M wrote:
    > I have come across a difficulty with an NSProxy subclass
    > on 10.3.9 which can be summed up with the following lines:
    >
    > Class p=[NSProxy class];
    > NSLog(@"class %@",p);
    >
    > The second line throws an exception:
    > *** Uncaught exception: <NSInvalidArgumentException>
    > *** -[NSProxy methodSignatureForSelector:] called!

    Actually this is a general problem. Briefly, the whole meta level of
    the NSProxy class hierarchy is broken, making the NSProxy class
    object non-functional. The problem comes from the fact that, in the
    current (broken) implementation, NSProxy's meta class inherits from
    the NSProxy class. This mimics the NSObject class system layout, but
    while this layout is correct for NSObject, it is not correct for
    NSProxy because of the differences in semantic between the concept of
    an object an the concept of a proxy.

    Executive summary: the NSProxy class object is broken. Do not use it,
    or write workarounds (like you did) to support the functionality you
    need.

    Best,

    Philippe Mougin
    http://www.fscript.org
  • NSProxy is not "broken". NSProxy happens to be an abstract class - which
    means first - it must be subclassed before it can be used; and second -
    there are certain methods which a subclass of NSProxy must implement. As it
    happens, NSProxy has two such methods - methodSignatureForSelector is one of
    them (forwardInvocation: is the other).

    And in fact all that an NSProxy subclass's methodSignatureForSelector does
    in most cases is simply to forward the call to the object being proxied
    (stored as a "realObject" instance variable in the example below):

    ­ (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    {
        return [realObject methodSignatureForSelector:aSelector];
    }

    And all of this information about NSProxy is easily found in the Foundation
    Reference for Objective-C documentation.

    Greg

    On 3/11/06 4:03 PM, "Philippe Mougin" <pmougin...> wrote:

    > Agent M wrote:
    >> I have come across a difficulty with an NSProxy subclass
    >> on 10.3.9 which can be summed up with the following lines:
    >>
    >> Class p=[NSProxy class];
    >> NSLog(@"class %@",p);
    >>
    >> The second line throws an exception:
    >> *** Uncaught exception: <NSInvalidArgumentException>
    >> *** -[NSProxy methodSignatureForSelector:] called!
    >
    > Actually this is a general problem. Briefly, the whole meta level of
    > the NSProxy class hierarchy is broken, making the NSProxy class
    > object non-functional. The problem comes from the fact that, in the
    > current (broken) implementation, NSProxy's meta class inherits from
    > the NSProxy class. This mimics the NSObject class system layout, but
    > while this layout is correct for NSObject, it is not correct for
    > NSProxy because of the differences in semantic between the concept of
    > an object an the concept of a proxy.
    >
    > Executive summary: the NSProxy class object is broken. Do not use it,
    > or write workarounds (like you did) to support the functionality you
    > need.
    >
    > Best,
    >
    > Philippe Mougin
    > http://www.fscript.org
    >
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/<greghe...>
    >
    > This email sent to <greghe...>
  • The issue is not over NSProxy but over its meta-class, which is indeed
    so crippled it can't even return its own description. Why shouldn't the
    meta-class be a full-blown object like all others?

    On Mar 11, 2006, at 7:30 PM, Greg Herlihy wrote:

    > NSProxy is not "broken". NSProxy happens to be an abstract class -
    > which
    > means first - it must be subclassed before it can be used; and second -
    > there are certain methods which a subclass of NSProxy must implement.
    > As it
    > happens, NSProxy has two such methods - methodSignatureForSelector is
    > one of
    > them (forwardInvocation: is the other).
    >
    > And in fact all that an NSProxy subclass's methodSignatureForSelector
    > does
    > in most cases is simply to forward the call to the object being proxied
    > (stored as a "realObject" instance variable in the example below):
    >
    > – (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    > {
    > return [realObject methodSignatureForSelector:aSelector];
    > }
    >
    > And all of this information about NSProxy is easily found in the
    > Foundation
    > Reference for Objective-C documentation.
    >
    > Greg

    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
    AgentM
    <agentm...>
    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
  • Le 12 mars 06 à 01:30, Greg Herlihy a écrit :

    > NSProxy is not "broken". NSProxy happens to be an abstract class -
    > which
    > means first - it must be subclassed before it can be used; and
    > second -
    > there are certain methods which a subclass of NSProxy must implement.

    [...]

    > And all of this information about NSProxy is easily found in the
    > Foundation
    > Reference for Objective-C documentation.
    >
    > Greg

    To clarify: what was discussed in this thread is the behavior of
    NSProxy at the class level: what happens when you try to manipulate
    the NSProxy class object itself (by opposition to instances of
    NSProxy). It is at the class (and metaclass) level that NSProxy is
    broken.

    Best,

    Philippe Mougin
    http://www.fscript.org

    > On 3/11/06 4:03 PM, "Philippe Mougin" <pmougin...> wrote:
    >
    >> Agent M wrote:
    >>> I have come across a difficulty with an NSProxy subclass
    >>> on 10.3.9 which can be summed up with the following lines:
    >>>
    >>> Class p=[NSProxy class];
    >>> NSLog(@"class %@",p);
    >>>
    >>> The second line throws an exception:
    >>> *** Uncaught exception: <NSInvalidArgumentException>
    >>> *** -[NSProxy methodSignatureForSelector:] called!
    >>
    >> Actually this is a general problem. Briefly, the whole meta level of
    >> the NSProxy class hierarchy is broken, making the NSProxy class
    >> object non-functional. The problem comes from the fact that, in the
    >> current (broken) implementation, NSProxy's meta class inherits from
    >> the NSProxy class. This mimics the NSObject class system layout, but
    >> while this layout is correct for NSObject, it is not correct for
    >> NSProxy because of the differences in semantic between the concept of
    >> an object an the concept of a proxy.
    >>
    >> Executive summary: the NSProxy class object is broken. Do not use it,
    >> or write workarounds (like you did) to support the functionality you
    >> need.
    >>
    >> Best,
    >>
    >> Philippe Mougin
    >> http://www.fscript.org
    >>
    >> _______________________________________________
    >> Do not post admin requests to the list. They will be ignored.
    >> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >> Help/Unsubscribe/Update your Subscription:
    >> http://lists.apple.com/mailman/options/cocoa-dev/<greghe...>
    >>
    >> This email sent to <greghe...>
    >
    >
    >
  • On Mar 11, 2006, at 7:20 PM, Philippe Mougin wrote:

    >> And all of this information about NSProxy is easily found in the
    >> Foundation
    >> Reference for Objective-C documentation.
    >>
    >> Greg
    >
    > To clarify: what was discussed in this thread is the behavior of
    > NSProxy at the class level: what happens when you try to manipulate
    > the NSProxy class object itself (by opposition to instances of
    > NSProxy). It is at the class (and metaclass) level that NSProxy is
    > broken.

    How do you figure that NSProxy is broken?

    It is documented to implement exactly 4 class methods (and being a
    root class inherits nothing more) - and "+ description" is not one of
    them (like it is for NSObject).

    It implements exactly what it says it does - just because it doesn't
    work like NSObject doesn't mean it's broken...

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    Widgetarium | the quickest path to widgets
  • >
    > How do you figure that NSProxy is broken?
    >
    > It is documented to implement exactly 4 class methods (and being a
    > root class inherits nothing more) - and "+ description" is not one of
    > them (like it is for NSObject).
    >
    > It implements exactly what it says it does - just because it doesn't
    > work like NSObject doesn't mean it's broken...

    Even if you do implement +description, it doesn't fix the exception.
    Try it. Instead you have to implement a private method in a category.

    What is really going on is that NSProxy's meta-class is in fact a weird
    NSProxy instead of an NSObject which I haven't been able to think of a
    rational explanation for. If you can think of one, please let us know-
    perhaps strict NSObject/NSProxy separation was the idea, but an NSProxy
    is useless without something to proxy...

    -M

    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
    AgentM
    <agentm...>
    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
  • On Mar 11, 2006, at 9:59 PM, Agent M wrote:

    >>
    >> How do you figure that NSProxy is broken?
    >>
    >> It is documented to implement exactly 4 class methods (and being a
    >> root class inherits nothing more) - and "+ description" is not one
    >> of them (like it is for NSObject).
    >>
    >> It implements exactly what it says it does - just because it
    >> doesn't work like NSObject doesn't mean it's broken...
    >
    > Even if you do implement +description, it doesn't fix the
    > exception. Try it. Instead you have to implement a private method
    > in a category.
    >
    > What is really going on is that NSProxy's meta-class is in fact a
    > weird NSProxy instead of an NSObject which I haven't been able to
    > think of a rational explanation for. If you can think of one,
    > please let us know- perhaps strict NSObject/NSProxy separation was
    > the idea, but an NSProxy is useless without something to proxy...

    Because, according to the documentation, the metaclass of a root
    class is suppose to be that class itself.  See <http://
    developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/
    index.html> down in the section where objc_class is defined:

    > isa
    > Points to the metaclass of this class. If this class is a
    > metaclass, the isa field points to the root metaclass (usually the
    > metaclass for NSObject, but also possibly the metaclass for NSProxy
    > or a root class of your own—a root class is any class that does not
    > inherit from another class). This also means that the isa field for
    > the metaclass of the root class points to itself.

    The point is that a root class shouldn't have a dependancy on another
    class, or it shouldn't be a root class.

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    Widgetarium | the quickest path to widgets
  • glenn andreas wrote :
    [...]
    > How do you figure that NSProxy is broken?
    > It is documented to implement exactly 4 class methods (and being a
    > root class inherits nothing more) - and "+ description" is not one
    > of them (like it is for NSObject).

    Remember that instance methods defined in a root class are also
    available on the class object itself. The Objective-C documentation
    states:

    "Normally, class objects can perform only class methods. But instance
    methods defined in the root class are a special case. They define an
    interface to the runtime system that all objects inherit. Class
    objects are full-fledged objects and need to share the same interface."

    and

    "When a class object receives a message that it can’t respond to with
    a class method, the runtime system determines whether there’s a root
    instance method that can respond. The only instance methods that a
    class object can perform are those defined in the root class, and
    only if there’s no class method that can do the job."

    Thus, the NSProxy class object should correctly respond to the
    instance methods it defines (this includes -description but also the
    methods declared in the NSObject protocol, since NSProxy adopts it).
    Currently, it does not. This means it is broken.

    Additionally, I'd like to insist on the fact that even without this
    rule the NSProxy class/metaclass system would be broken. Indeed,
    currently the superclass of the NSProxy metaclass is NSProxy. This is
    a logical error. Think about it: it means that the NSProxy class
    itself is a kind of proxy, which is conceptually incorrect. NSProxy
    instances are proxies, but we don't want the NSProxy class itself to
    be a proxy. From a conceptual and logical point of view this is
    meaningless (and concretely the result is that the current NSProxy
    class object is generally useless, for no good reason).

    While it makes sense, in an object-oriented language, for the concept
    of object (e.g., the NSObject class) to be itself an object (e.g., to
    be instance of a metaclass that inherits from NSObject), it make no
    sense for the concept of proxy (e.g., the NSProxy class) to be itself
    a proxy. It should be a regular object. We are not in a proxy-
    oriented language (where all things would be proxies), but in an
    object-oriented language (things are objects).

    Best,

    Philippe Mougin
    http://www.fscript.org
  • I did some more digging on why a private method is required to be
    implemented in order for objects to be successfully passed to NSLog
    (CFLog). Here's the relevant code:

    http://cvs.opendarwin.org/cgi-bin/cvsweb.cgi/src/CoreFoundation/
    Base.subproj/CFRuntime.c?rev=1.3&content-type=text/x-cvsweb-markup

    CFStringRef CFCopyDescription(CFTypeRef cf) {
    #if defined(DEBUG)
        if (NULL == cf) HALT;
    #endif
        CFTYPE_OBJC_FUNCDISPATCH0(CFStringRef, cf, "_copyDescription");
    ...

    traced from the heavy-duty function __CFParseFormatSpec in:
    http://cvs.opendarwin.org/cgi-bin/cvsweb.cgi/src/CoreFoundation/
    String.subproj/CFString.c?rev=1.5&content-type=text/x-cvsweb-markup

    This function is called on every ObjC object passed to NSLog() so root
    classes that fail to implement it cannot be printed. Anyway, I would
    like to point to this as a good example of why open source code is
    good.

    rdar://4482973 (expected to be flagged as "Expected Behavior")

    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
    AgentM
    <agentm...>
    ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬ ¬
previous month march 2006 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today