xcode 3.2.2 and objective-c 2.0 and debug: where are my object's property/instance variable values in debug?
Asked Answered
R

3

8

working on a mac os project (meaning not iPhone) requiring 10.6 and is 64bit, allows me to use properties to generate both accessor methods and instance variables in the header file. but, during debug, i'm not seeing how to look at the object's properties values after they have been populated. is there some build setting that needs to be turned on?

if i am declaring an object's instance variables (between {} in the header), then i can see those values (when they are used) during debug either in the debug window itself, or by using the cursor-hover over the highlighted line trick in the editor during a break, or by doing cli in gdb like 'p *object' for instance.

old way:

@class Suit;
@interface Card : NSObject 
{
    NSNumber *playOrder;
    Suit *suit;
    NSNumber *displayNumber;
    NSNumber *orderIndex;
}
@property(nonatomic, retain) Suit *suit;
@property(nonatomic, retain) NSNumber *displayNumber;
@property(nonatomic, retain) NSNumber *orderIndex;

new way:

@class Suit;
@interface Card : NSObject 

@property(nonatomic, retain) Suit *suit;
@property(nonatomic, retain) NSNumber *displayNumber;
@property(nonatomic, retain) NSNumber *orderIndex;
@property(nonatomic, retain) NSNumber *playOrder;

in this new-fangled 10.6 required 64bit idea (which seems simpler to me) none of these debug methods display the object's values. i figure that i must have something turned off, because this newer idea, doesn't seem better.

gdb results for old way:

(gdb) po newCard
New Card : 0 of Suit : Hearts (NSCalibratedRGBColorSpace 1 0 0 1). with orderIndex of: 1
(gdb) p *newCard
$1 = {
  <NSObject> = {
    isa = 0x100002188
  }, 
  members of Card: 
  playOrder = 0x0, 
  suit = 0x200053a20, 
  displayNumber = 0x20001bac0, 
  orderIndex = 0x200012de0
}
(gdb)

gdb results for new way:

(gdb) po newCard
New Card : 0 of Suit : Hearts (NSCalibratedRGBColorSpace 1 0 0 1). with orderIndex of: 1
(gdb) p *newCard
$3 = {
  <NSObject> = {
    isa = 0x100002188
  }, <No data fields>}
(gdb) 

so looking at the docs for objective-c 2.0:

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW3

describes what i am referring to (synthesizing instance variables in 'modern' runtime), but what isn't said anywhere, is that if you do this, the values will not be available during debugging.

i've found an SO page with pertinent information, but not focused on this effect: Using instance variables with Modern Runtime

what did i miss?

Rahmann answered 3/6, 2010 at 23:1 Comment(2)
Is it possible you have turned on garbace collection? Try turning it off and see if the debugger picks up on the fields then.Erst
yes garbage collection is on in both example tests.Rahmann
L
2

In GDB, you can use property getters to access dynamic ivars:

(gdb) po [newCard displayNumber]
0
Lashoh answered 19/11, 2010 at 3:9 Comment(1)
outis, thanks for your answer. it's actually what i needed. i was stuck in thinking that i should use newCard.displayNumber (note dot syntax) and when that didn't work, i should use p* newCard, and follow from that result. then i was stuck not seeing any usable result from that.Rahmann
E
2

I assume that you are @synthesizing those variables?

You may also need { } in the interface, so the compiler knows where to put it.

@interface Card : NSObject
{

}

I would avoid this kind of syntax... especially if you define the properties yourself.

Also, look up <objc/runtime.h> and see if you can print a list of ivars for the class. I use the following all the time for debugging methods or classes from APIs that have no documentation.

    unsigned int total_method_count = 0;
    Method * method_list = class_copyMethodList(object_getClass([obj class]), &total_method_count);
    @try
    {
        int method_counter = 0;
        for (method_counter = 0; method_counter < total_method_count; method_counter++)
        {
            Method method = method_list[method_counter];
            // check if method the KVC getter you are interested in
            NSLog(@"Method: %s", sel_getName(method_getName(method)));
        }
    } @catch (NSException *e) {
        //Do Nothing
    }
Esophagus answered 10/6, 2010 at 11:45 Comment(4)
yes, the .m file has @synthesize for the properties in both examples. as to using '{}' in the second example, i am using the idea that if a project is set to be 64-bit, and requiring 10.6 to run, then instance variables can be synthesized, and the '{}' is not necessary. thus my extreme surprise finding no data to use in debug, so sure i have something wrong. i'll try your code and report back. thanks, stephen.Rahmann
i can see where the above idea can be helpful, as well as using the runtime header functions in debugging as a strategy, and will probably help other folks too. what i am asking about is that it seems that if i use synthesized ivars in creating projects that are 64-bit, 10.6 runtime, then i'm not seeing debugging data references, and to me, this seems so odd, (to not be able to use gdb or xcode debug) that i'm sure i've got something missing in my setup. so that's the basis of my question: 'what did i miss?'.Rahmann
All I was referencing was the fact that the compiler may not be generating the ivars at all. Hence why you should use the runtime to make sure they're generated and not just rely on (gdb) or the XCode debugger. Also, since the compiler is not doing anything intelligent, you may want to add the { } to make sure the compiler knows where to put that code. Unfortunately that's as far as I can help you. If you can't see your ivars with the runtime.h then the "new" way is just a bunch of horse-malarky and you should never use "invisible" syntax like that anyway.Esophagus
sorry it took a while to get back to you.thank you for the advice. i have changed my 'real' project adding back {}. i was using this book:'Cocoa and Objective:Up and Running', and the author uses this idea througout his examples, however the book doesn't cover gdb.Rahmann
L
2

In GDB, you can use property getters to access dynamic ivars:

(gdb) po [newCard displayNumber]
0
Lashoh answered 19/11, 2010 at 3:9 Comment(1)
outis, thanks for your answer. it's actually what i needed. i was stuck in thinking that i should use newCard.displayNumber (note dot syntax) and when that didn't work, i should use p* newCard, and follow from that result. then i was stuck not seeing any usable result from that.Rahmann
G
2

I had the same problem with synthesized ivars. My solution was to switch to the LLVM 1.6 compiler in XCode 3.25. This brought back debugger tooltips (most helpful to me), but the variables window still fails to show the ivars.

Goodwill answered 24/1, 2011 at 20:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.