IB instantiating objects
I'm working on developing a Pascal Objective-C bridge like RubyObjc and have run across a problem I can't seem to work around with IB. I very new to Cocoa btw, so I hope this makes sense. Maybe I'm asking in the wrong place also. ;) I have noticed that when a nib is loaded it must allocate an instance of the class that I added to the nib and when actions are sent to their target (by dragging connections to that class), THAT instance is used as the self parameter (the first) in the Pascal function (this parameter is hidden in Objective-C code). That means I have no opportunity to set an instance variable that contains a reference to the Pascal object, and thus access it's instance variables and methods. Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
NO, it supports subclassing. Do you know what method I could override (and return my instance) before the NIB is loaded so I can control it's isntance variables? I think maybe a low-level protocol like init could perhaps work. Thanks. On Mar 24, 2009, at 12:15 AM, Bill Bumgarner wrote: On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
Hey Josef - When IB instantiates an object in a NIB file that has the custom class set, it will instantiate it with either init, initWithFrame:, or initWithCoder: depending on the type of object. Here's a link tot he relevant documentation: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/1051i-CH4-SW19 Jon Hess On Mar 23, 2009, at 5:36 PM, Gmail wrote: NO, it supports subclassing. Do you know what method I could override (and return my instance) before the NIB is loaded so I can control it's isntance variables? I think maybe a low-level protocol like init could perhaps work. Thanks. On Mar 24, 2009, at 12:15 AM, Bill Bumgarner wrote: On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/jhess%40apple.com This email sent to jh...@apple.com ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
Thanks! I think that document explains everything I need to know to take control over IB. This is more Objective-C related by maybe you have a quick tip. My first tests suggest that my method for overriding is not correct because overriding init is getting invoked from all sorts of other classes (like NSFileManager to name a few) when the NIB is loading. I use class_getInstanceMethod (with the instance of the custom class I registered with the objective-c runtime) to get the method then replace the implementation with my function pointer. This method worked before for overriding drawRect: in NSView so I'm not sure what is different now. Any ideas? On Mar 24, 2009, at 8:02 AM, Jonathan Hess wrote: Hey Josef - When IB instantiates an object in a NIB file that has the custom class set, it will instantiate it with either init, initWithFrame:, or initWithCoder: depending on the type of object. Here's a link tot he relevant documentation: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#/ /apple_ref/doc/uid/1051i-CH4-SW19 Jon Hess On Mar 23, 2009, at 5:36 PM, Gmail wrote: NO, it supports subclassing. Do you know what method I could override (and return my instance) before the NIB is loaded so I can control it's isntance variables? I think maybe a low-level protocol like init could perhaps work. Thanks. On Mar 24, 2009, at 12:15 AM, Bill Bumgarner wrote: On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/jhess%40apple.com This email sent to jh...@apple.com Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
On Mar 23, 2009, at 9:30 PM, Gmail wrote: Thanks! I think that document explains everything I need to know to take control over IB. This is more Objective-C related by maybe you have a quick tip. My first tests suggest that my method for overriding is not correct because overriding init is getting invoked from all sorts of other classes (like NSFileManager to name a few) when the NIB is loading. I use class_getInstanceMethod (with the instance of the custom class I registered with the objective-c runtime) to get the method then replace the implementation with my function pointer. This method worked before for overriding drawRect: in NSView so I'm not sure what is different now. Any ideas? class_getInstanceMethod searches the entire class hierarchy. So, if the class you're working with didn't override that implementation you'll be replacing the superclass' implementation. If you call class_addMethod on self with the result of class_getMethodImplemenation you'll be adding it to the subclass if it's not already overridden. After that calling method_exchangeImplementations will only affect that class. Ashley On Mar 24, 2009, at 8:02 AM, Jonathan Hess wrote: Hey Josef - When IB instantiates an object in a NIB file that has the custom class set, it will instantiate it with either init, initWithFrame:, or initWithCoder: depending on the type of object. Here's a link tot he relevant documentation: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#/ /apple_ref/doc/uid/1051i-CH4-SW19 Jon Hess On Mar 23, 2009, at 5:36 PM, Gmail wrote: NO, it supports subclassing. Do you know what method I could override (and return my instance) before the NIB is loaded so I can control it's isntance variables? I think maybe a low-level protocol like init could perhaps work. Thanks. On Mar 24, 2009, at 12:15 AM, Bill Bumgarner wrote: On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
On Mar 24, 2009, at 10:01 AM, Ashley Clark wrote: On Mar 23, 2009, at 9:30 PM, Gmail wrote: Thanks! I think that document explains everything I need to know to take control over IB. This is more Objective-C related by maybe you have a quick tip. My first tests suggest that my method for overriding is not correct because overriding init is getting invoked from all sorts of other classes (like NSFileManager to name a few) when the NIB is loading. I use class_getInstanceMethod (with the instance of the custom class I registered with the objective-c runtime) to get the method then replace the implementation with my function pointer. This method worked before for overriding drawRect: in NSView so I'm not sure what is different now. Any ideas? class_getInstanceMethod searches the entire class hierarchy. So, if the class you're working with didn't override that implementation you'll be replacing the superclass' implementation. If you call class_addMethod on self with the result of class_getMethodImplemenation you'll be adding it to the subclass if it's not already overridden. After that calling method_exchangeImplementations will only affect that class. Hmmm, I overrode the superclasses implementation, i.e. NSObject, which sounds about right considering the results. So, I need to be using class_addMethod for init because my new class has no implementation for that method. I think the previous attempt to override NSView worked because drawRect: DID have an implementation for that selector already added to the runtime, which is not the case with my new class. Thank you Ashley I think you are correct. Is there anyway way to determine if a class has an implementation for a method so I can decide to add a new method or override an existing? As it stands I don't know in code when I should add or exchange implementations. Ashley On Mar 24, 2009, at 8:02 AM, Jonathan Hess wrote: Hey Josef - When IB instantiates an object in a NIB file that has the custom class set, it will instantiate it with either init, initWithFrame:, or initWithCoder: depending on the type of object. Here's a link tot he relevant documentation: http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#/ /apple_ref/doc/uid/1051i-CH4-SW19 Jon Hess On Mar 23, 2009, at 5:36 PM, Gmail wrote: NO, it supports subclassing. Do you know what method I could override (and return my instance) before the NIB is loaded so I can control it's isntance variables? I think maybe a low-level protocol like init could perhaps work. Thanks. On Mar 24, 2009, at 12:15 AM, Bill Bumgarner wrote: On Mar 22, 2009, at 6:26 PM, Gmail wrote: Is there anyone who is aware how this was accomplished by the other bridges or if I can force IB to not instantiate the classes, or maybe replace the instance with my own? It seems like I need a way to access the instances of those classes inside the nib but I don't think that can be done. Any ideas are greatly appreciated. Thank you. RubyCocoa and PyObjC work by creating the class before the NIB is loaded.From your description, it sounds like your bridge doesn't support subclassing. If so, that'll make your bridge considerably more difficult to integrate with Cocoa. b.bum Regards, Josef Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
On Mar 23, 2009, at 10:31 PM, Gmail wrote: On Mar 24, 2009, at 10:01 AM, Ashley Clark wrote: On Mar 23, 2009, at 9:30 PM, Gmail wrote: Thanks! I think that document explains everything I need to know to take control over IB. This is more Objective-C related by maybe you have a quick tip. My first tests suggest that my method for overriding is not correct because overriding init is getting invoked from all sorts of other classes (like NSFileManager to name a few) when the NIB is loading. I use class_getInstanceMethod (with the instance of the custom class I registered with the objective-c runtime) to get the method then replace the implementation with my function pointer. This method worked before for overriding drawRect: in NSView so I'm not sure what is different now. Any ideas? class_getInstanceMethod searches the entire class hierarchy. So, if the class you're working with didn't override that implementation you'll be replacing the superclass' implementation. If you call class_addMethod on self with the result of class_getMethodImplemenation you'll be adding it to the subclass if it's not already overridden. After that calling method_exchangeImplementations will only affect that class. Hmmm, I overrode the superclasses implementation, i.e. NSObject, which sounds about right considering the results. So, I need to be using class_addMethod for init because my new class has no implementation for that method. I think the previous attempt to override NSView worked because drawRect: DID have an implementation for that selector already added to the runtime, which is not the case with my new class. Thank you Ashley I think you are correct. Is there anyway way to determine if a class has an implementation for a method so I can decide to add a new method or override an existing? As it stands I don't know in code when I should add or exchange implementations. You could call class_copyMethodList and iterate through that to find only methods defined directly on a class, but there's no harm in just calling class_addMethod. It will add an override of a superclass' implementation but will not replace an existing implementation if one was already defined on the class. So, there's no need to decide between add or exchange. Do both! eg. (typed in Mail, YMMV) Class klass = ... SEL selector = ... Method originalMethod = class_getInstanceMethod(klass, selector); class_addMethod(klass, selector, class_getMethodImplementation(klass, selector), method_getTypeEncoding(originalMethod)); class_replaceMethod(...); You'll get the right behavior every time, assuming right means you only want to replace the method on the class and not its' superclasses. Ashley ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
Great, thanks. I almost have this working but with one little problem. 1) I add the init method to my class 2) When init is invoked from the NIB I call objc_msgSend with the selector init which returns the new instance of the class (retrieved from objc_getClass) I previously registered with the runtime and added instance variables. 3) I call class_getInstanceVariable to get the instance variable I need to assign the reference to the wrapper class. Here class_getInstanceVariable returns nil which it never did before. I'm using the 1.0 runtime for now btw, but I get the class of the instance by using the isa field of the structure and give that class as the parameter to class_getInstanceVariable. This worked with other objects so I think I may have created the instance wrong. Is simply sending init to the class not enough? I tried calling alloc also but it entered into an infinite loop. Also, do I need to being the self parameter in this process that is the first parameter in the method? I find it strange I have another instance of this object I'm trying to replace, what should I do with it? Is it leaking memory? Thanks for helping with this I appreciate it. On Mar 24, 2009, at 11:22 AM, Ashley Clark wrote: You could call class_copyMethodList and iterate through that to find only methods defined directly on a class, but there's no harm in just calling class_addMethod. It will add an override of a superclass' implementation but will not replace an existing implementation if one was already defined on the class. So, there's no need to decide between add or exchange. Do both! eg. (typed in Mail, YMMV) Class klass = ... SEL selector = ... Method originalMethod = class_getInstanceMethod(klass, selector); class_addMethod(klass, selector, class_getMethodImplementation(klass, selector), method_getTypeEncoding(originalMethod)); class_replaceMethod(...); You'll get the right behavior every time, assuming right means you only want to replace the method on the class and not its' superclasses. Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: IB instantiating objects
I'm sorry! The light bulb just went off as soon as I sent that last message. I'm NOT supposed to init a NEW instance, but use that instance and simply modify it, which works perfectly. Please ignore that last message, this issue is solved and thank you very much for helping. Pascal users on Mac thank you also. On Mar 24, 2009, at 11:22 AM, Ashley Clark wrote: On Mar 23, 2009, at 10:31 PM, Gmail wrote: On Mar 24, 2009, at 10:01 AM, Ashley Clark wrote: On Mar 23, 2009, at 9:30 PM, Gmail wrote: Thanks! I think that document explains everything I need to know to take control over IB. This is more Objective-C related by maybe you have a quick tip. My first tests suggest that my method for overriding is not correct because overriding init is getting invoked from all sorts of other classes (like NSFileManager to name a few) when the NIB is loading. I use class_getInstanceMethod (with the instance of the custom class I registered with the objective-c runtime) to get the method then replace the implementation with my function pointer. This method worked before for overriding drawRect: in NSView so I'm not sure what is different now. Any ideas? class_getInstanceMethod searches the entire class hierarchy. So, if the class you're working with didn't override that implementation you'll be replacing the superclass' implementation. If you call class_addMethod on self with the result of class_getMethodImplemenation you'll be adding it to the subclass if it's not already overridden. After that calling method_exchangeImplementations will only affect that class. Hmmm, I overrode the superclasses implementation, i.e. NSObject, which sounds about right considering the results. So, I need to be using class_addMethod for init because my new class has no implementation for that method. I think the previous attempt to override NSView worked because drawRect: DID have an implementation for that selector already added to the runtime, which is not the case with my new class. Thank you Ashley I think you are correct. Is there anyway way to determine if a class has an implementation for a method so I can decide to add a new method or override an existing? As it stands I don't know in code when I should add or exchange implementations. You could call class_copyMethodList and iterate through that to find only methods defined directly on a class, but there's no harm in just calling class_addMethod. It will add an override of a superclass' implementation but will not replace an existing implementation if one was already defined on the class. So, there's no need to decide between add or exchange. Do both! eg. (typed in Mail, YMMV) Class klass = ... SEL selector = ... Method originalMethod = class_getInstanceMethod(klass, selector); class_addMethod(klass, selector, class_getMethodImplementation(klass, selector), method_getTypeEncoding(originalMethod)); class_replaceMethod(...); You'll get the right behavior every time, assuming right means you only want to replace the method on the class and not its' superclasses. Ashley Regards, Josef ___ 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com