Re: Debugging a specific object
Re: Debugging a specific object
- Subject: Re: Debugging a specific object
- From: Jamie <email@hidden>
- Date: Wed, 7 Jul 2004 17:44:05 +0100
Tim...
thanks for the response. In the interim I played and found out exactly
what you just said. Effectively you usually only need to change 3
lines of code. I write a small subclass that simply NSLogged the
invocation details in the same way you used printf. This just seems
like such a great tool for reverse engineering things where you dont
have access to the source!
I did find one instance where it wouldn't work however, and I was
wondering if anyone with more experience could shed a little light on
why. I proxy'd an NSArray with my new proxy subclass and then let
things run. In my code I had a call to generate an NSEnumerator using
the objectEnumerator method of NSArray. This failed and the program
crashed. I dont have the error to hand but it was something along the
lines of "NSProxy doesn't support selector objectEnumerator". from
reading the source code in that apple example, it also appears that
there are some methods you can't proxy (possibly multi argument
ones???). Does anyone know what these restrictions amount to?
Many thanks
Jamie
On 7 Jul 2004, at 17:12, Tim Hewett wrote:
Jamie,
On 7 Jul 2004, at 16:05, Jamie wrote:
NEWBIE ALERT!!!!
OK. I'm posting coz I like the sound of this for digging into the
guts of how things actually happen in Obj-c / cocoa.
so, from my understanding the proxy object gets put between your code
and the real object you want to use. You forward messages to the
real object using forwardInvocation, so you can log some data for
example before you forward the message. would there be an easy way
to be able to drop one of these objects into your code without having
to alter every call to the object you would be proxying? Sounds very
useful but if you have to go through all your code and replace every
call to your original class with a new proxy class it could be
tedious to use.
You don't have to replace the calls, the calls just go to the proxy
instead of the real object. So if you have (e.g.) a subclass of
NSButton called MyButton with your instance called "button"
and you want to see all the calls made to that object, just create
a proxy in the same way as in the developer CD example
mentioned, set the target to be the button instance (I cut the
developer example from 2 targets to 1 since it was all | needed),
and change the button instance to be the proxy object.
So instead of:
MyButton *button = [[MyButton alloc] init]; // or whatever you do to
create the button
you do:
MyButton *tmpButton = [[MyButton alloc] init]; // or whatever you do
to create the button
id button = [[TargetProxy alloc] initWithTarget:tmpButton];
// continue making calls to button, forget it is a proxy
Then all method calls on button go to the proxy, where in the
forwardInvocation: method you can add the line:
printf( "Proxy calling %s, n_args is %d\n", sel_getName( [invocation
selector] ), [[realObject1 methodSignatureForSelector:[invocation
selector]] numberOfArguments] );
which shows each method call as it happens.
Tim. You have any objections to sharing the actual code you used to
do your debugging or was it just the code in the example you gave?
More or less the exact ForwardInvocation example code, but
cut down to one target instance variable and with the above
printf added.
Jamie
Regards,
Tim.
On 7 Jul 2004, at 15:19, Tim Hewett wrote:
Louis,
Absolutely fantastic, thank you so, so much. Even better there is
a real life example of NSProxy in use in the developer examples
for 10.3, in /Developer/Examples/Foundation/ForwardInvocation,
virtually a case of "paste and go".
I never knew about NSProxy, but this is one very useful class, it
does exactly what you describe.
Thanks again, in 15 minutes I've now solved the problem which
several days have been thrown at (which was caused by there being
a hidden method in NSCell called when the view needs to discover
whether a cell needs to be redrawn when the window changes key
state - documentation please someone at Apple!).
Regards,
Tim.
On 7 Jul 2004, at 11:37, Louis C. Sacha wrote:
Hello...
You could create a simple subclass of NSProxy that either logs the
method that is being called in it's implementation of
forwardInvocation:, or has a breakpoint set within the
forwardInvocation: method.
Instead of using or returning your object directly, return the
proxy to the object.
If your object is a view that is created in a nib, you'll need an
outlet to the view and you can replace it with a proxy in the
awakeFromNib method by doing the following:
[[problemView superview] replaceSubview:problemView with:(NSView
*)proxyForProblemView];
Note: if you use the outlet for anything other than making the
switch, you'll want to change the outlet to point to the proxy as
well.
Hope that helps,
Louis
Hi,
I'm just wondering if there is a way to have the XCode
debugger trace or break each time a particular Objective
C object receives a call to any of its selectors, including
those it has inherited from a higher class. I need to be
able to see how Cocoa is calling my object as it is being
displayed differently to how I want it to be, and so far
attempts to debug by overloading inherited methods have
been fruitless.
Normally XCode lets you break in specific methods, but
I need to have it do this for all methods in a specific object.
Any help greatly appreciated.
Regards,
Tim.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.