Re: [Pyobjc-dev] Categories (was: Subclassing NSTextField)
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2002-12-18 18:48:55
|
On Wednesday, Dec 18, 2002, at 16:44 Europe/Amsterdam, Peter Montagner wrote: > I don't know if this is what you want but it may help: > > http://www.cocoadev.com/index.pl?MethodSwizzling Swapping methods? Hah, we can do better than that :-) Nice to see that it is not only us bridge-builders that poke around in the Objective-C runtime. > Peter > > On Thursday, December 19, 2002, at 01:41 AM, bb...@ma... wrote: > >> On Wednesday, Dec 18, 2002, at 01:32 US/Eastern, Ronald Oussoren >> wrote: >>> On Tuesday, Dec 17, 2002, at 21:08 Europe/Amsterdam, bb...@ma... >>> wrote: >>>> On Tuesday, Dec 17, 2002, at 14:25 US/Eastern, Steven D. Arnold >>>> wrote: >>>>> On a related note, is there any mechanism to implement categories >>>>> in pyobjc? >>>>> I thought this question had been asked before, but I couldn't find >>>>> it in my >>>>> archive. >>>> >>>> Good question: Ronald? >>> >>> Not really. You can of course implemenent methods from a category >>> for your own subclasses (e.g. like the text* categories Bill >>> mentioned in the previous message), but you cannot add new methods >>> to existing Objective-C classes. You can add new methods to >>> subclasses defined in Python. >> >> Some random notes... (more Internet as a todo list -- also a lot of >> this can be answered more specifically by looking at the darwin >> source -- i don't have net connectivity right now, though). >> >> How are categories found in bundles currently loaded into the >> runtime? Specifically, I see a declaration for a category structure >> in objc.h/objc-load.h/objc-class.h, but the only add methods API is >> this... >> >> OBJC_EXPORT void class_addMethods(Class, struct objc_method_list *); >> OBJC_EXPORT void class_removeMethods(Class, struct objc_method_list >> *); >> >> ... which is also interesting in that it appears that removing >> methods is naturally supported by ObjC? Didn't know that. The class_addMethods function is probably what is used to load categories. Categories are not really objects in the runtime. >> >>> Some other useful things you cannot do at the moment (using the >>> Internet as my Todo list :-) are: >>> - Adding new methods to subclassses implemented in Python if those >>> methods override/extend existing methods. You can do this, but your >>> method won't be called if someone tries to access this method from >>> Objective-C. >> >> Is this a matter of invoking class_addMethods() with the appropriate >> objc_method_list? Yes it is and that should be easy enough. With the current codebase this is only doable if you're adding to a python-defined class, when I get around to playing with libffi again we should be able to also add methods to pure Objective-C classes. >> >>> - Removing methods from subclasses implemented in Python, if those >>> methods override/extend existing methods. Again you can actually do >>> this, but this doesn't have the right semantics. >> >> Not sure what you mean. It certainly isn't something that is >> commonly done in ObjC-- I don't think I have ever seen methods >> removed from classes in the 15 years I have been doing ObjC-- but the >> API appears to support this. This assumes that class_removeMethods() >> is more than a no-op. When you're experimenting it might be usefull to just delete an existing method from a Python class (maybe because you just added it and found out this wasn't really what you wanted to do). If you remove a method you want that calls to that selector now go to the superclass. Say you have: class FooObject (NSObject): def hash(self): return 0xff obj = FooObject.alloc().init() After experimenting with this you decide that your implementation isn't very usefull and decide you can to without it: del FooObject.hash You'd expected that obj.hash() ends up calling NSObject.hash instead of causing an error because the Python class no longer implements hash. >> >>> - Redefine an existing class. This is a feature: Because Objective-C >>> has a flat namespace and python doesn't you might otherwise >>> accidently replace and existing class. It is also not really >>> possible to implement this without memory leaks. >> >> Right. In this case, enforcing the ObjC semantics of >> once-a-class-always-the-same-class is the way to go. During incremental development it might be usefull to replace existing classes, but that should not be the default behaviour. Just completely redefining an existing class by adding and removing methods might be just as usefull. In Python 2.3 it will also be possible to dynamicly change the class hierarchy for new-type classes. Supporting this in PyObjC might be neat. >> >>> All of these would be usefull for incremental development and may be >>> added in some future version (that includes support for categories). >> >> It would be useful for more than incremental development. >> >> Categories-- as much as they can be horrendously abused-- are a >> fairly fundamental part of the ObjC development experience. >> >> If we can redefine existing methods on the fly-- swizzle methods-- >> then we can build some incredibly powerful introspection and >> debugging tools. Namely, we could potentially replace existing ObjC >> methods in a fashion where the existing functionality remains >> unchanged but some random method is invoked before and/or after the >> normal implementation. For debugging, this would be HUGE! Doing that is not too hard. If you want to do this with 'pure' Objective-C classes things get a harder, but using libffi (or a simular library) this should still be doable. But you shouldn't trust my judgement on timing: I once said that getting PyObjC in a more usefull shape (w.r.t. using NIB files) should take about 2 weeks :-) Ronald |