Is it possible to stop on a breakpoint in an instance of an object? - objective-c

I've tried creating a breakpoint within a class definition, stopping on the message sent to an object instance, hoping it would then jump to the class code and allow me to walk through line by line and see the values of the local variables.
However, I'm going to venture out and say "no, this should not be possible", as there could be multiple instances of the class in memory. If someone could give a better explanation, that would be grand.
(As a side note, my alternative is excessive NSLogging of the runtime data.)

Yes, it is possible! You can add a condition to a breakpoint:
http://d.pr/yZVB+
http://d.pr/pWOB+
The program will only pause at this breakpoint when the condition is satisfied. You could choose a condition such as self == _myGlobalInstanceOfInterest.
If you don't want to store the instance in a variable, you might, for example, start the breakpoint without a condition — and then when you figure out which instance you want as the program is running, use p myObject to get the address, and then just set the condition to use the that address (such as self == 0x8badf00d).

I take it you want to break upon a message being sent to a particular instance?
Read the Xcode documentation on breakpoints and watchpoints. Basically, you can set a condition on a breakpoint so that it will automatically continue if self isn't the instance you're interested in.

Assuming you're talking about something like this:
- (void)eatAPieceOfFruit: (NSFruit *)fruit {
NSString * fruitType = [fruit species];
BOOL hasSeeds = [fruit hasSeeds];
NSInteger deliciousnessRating = [self enjoymentOfFruitType: fruitType];
NSString * reactionToEating = [self phraseForFruitType: fruitType];
// Breakpoint set here
}
The debugger has access to and knows the name of any variable that's in scope -- any variable that you would be able to use in the actual code at the line where you broke, you can also get to via the debugger. So, at the debugger prompt, type:
po reactionToEating
(that's "po" for "print object"), or the name of any other local variable to see what it is. If you want to call a method on an object that's in scope you can do so:
print (int)[reactionToEating length]
po [reactionToEating capitalizedString]

Related

Why does LLDB does not acknowledge complete selector name as a breakpoint?

I have a function name declared as follows in OBjective C :
- (void)placeViews:(CGSize)screenSize;
In my viewDidLoad i call this function, and I want to put a breakpoint when it is called as such:
[self placeViews:size]
So in LLDB I am entering the following breakpoint command:
breakpoint set --selector placeViews:screenSize
But the LLDB is unable to resolve the breakpoint
However, when I only use "placeViews:" as the selector it finds the selector and adds the breakpoint.
What I don't get is why it finds the selector when I use "placeViews:", but it doesn't find it when i used the entire method name "placeViews:screenSize".
Why is that?
So what happens when I have multiple methods like another one such as "placeViews:screenSize:oneMoreThing" and I want to set a breakpoint only on this method, how can LLDB distinguish between "placeViews:screenSize" and "placeViews:screenSize:oneMoreThing" ?
thank you!
-Malena
placeViews:screenSize is not the selector name, the selector is just "placeViews:". The selector name does not include the variable name that is passed to the message that that selector indicates (screenSize in your case.)
That actually makes sense if you think about it, because users have to provide the "placeViews:" part of the selector when they call the method, but "screenSize" has no part of how they call it. Also, it is NOT an error to use screenSize in your #interface and a completely different name in the #implementation. So it really shouldn't be part of the name the runtime conses up for the message.
You can verify this, for instance run this in Terminal
$ otool -o | grep placeViews
name 0x100000f56 placeViews:
No mention of screenSize.

view the return value of method invocation

How could I view the value of [fetchedResultsController sectionIndexTitles] in the debugger without change the code?
return [fetchedResultsController sectionIndexTitles];
Currently, I use to trick of add an tempory variable s and then use "print the descriptions of 's'" command. But this method requires me change the code so it is not convenient.
NSArray *s= [fetchedResultsController sectionIndexTitles];
return s;
Similar, it would be very helpful to be able to see the value of [a method1] in following statement:
[b [a method1]]
Do use breakpoints ... Add breakpoint to your return line, right click on breakpoint, edit breakpoint and now you have two options ...
Add Action Debugger Command ...
expr (void)NSLog( #"%#", [fetchedResultsController sectionIndexTitles] );
... or Log Message Action in a similar way and turn on Automatically continue after evaluating.
What it does?
Every time you hit your line with breakpoint, your application is paused, breakpoint actions are processed and as you did turn on Automatically continue after evaluating, your program continues when these breakpoint actions are processed. This is the way how to log, inspect, ..., without modifying your code.
I found the trick:
After the breakpoint is hit, Simply type following command in the LLDB would do the job:
po [self.fetchedResultsController sectionIndexTitles]
Where po is an abbreviation for expression -o -- used to print the object description of the value resulting from the expression.
The return value is visible in Xcode debugger, immediately after returning from a function call (i.e. immediately after hitting the the "step out" button). See below screenshot for example:

Calling Objective-C methods

Let's say I have a method called foo. What's the difference between:
[self foo];
and
[self performSelector:#selector(foo)];
Are they the same? The first one seems so much easier, so why would you ever want to use the second one?
From the docs:
The performSelector: method is equivalent to sending an aSelector message directly to the receiver. For example, all three of the following messages do the same thing:
id myClone = [anObject copy];
id myClone = [anObject performSelector:#selector(copy)];
id myClone = [anObject performSelector:sel_getUid("copy")];
However, the performSelector: method allows you to send messages that aren’t determined until runtime. A variable selector can be passed as the argument:
SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector:myMethod];
Well, say you were getting a SEL from somewhere else, and you just wanted to execute it, you'd use this method.
Otherwise, yeah, you'd usually want to use the first example.
The first sends a message to an object and so does the second. In almost all cases, you should use the first. It's quicker and clearer. However, the second has its uses. For instance, you can use it in a situation where you would need to supply a call back.
Another powerful use is in combination with NSSelectorFromString(). You can literally decide what message to use at run time based on a string in a configuration file or from user input (don't forget to validate it!). You can even build selector names using NSString -stringWithFormat: etc. For instance, this parser kit uses the technique to inform the program when parser rules have been matched.

How can I make sure an object has finished initialising before using it?

Writing some Objective-C in one method, I call +alloc, then -init to set up an object.
object = [[MyClass alloc] init];
[object useFor:whatever];
The next few lines of code use the newly created object. If the aforementioned -init takes too long, I’m sure the program won’t “wait” before starting to use the new object, will it? If not, is there a quick way to assure the -init is completed?
I sometimes see programmers who write something along the lines of
if(object = [[MyClass alloc] init]) {
[object useFor:whatever];
}
Is this what I should go for?
When you call init the program will not go on to the next line until the init method returns. By the time you've reached the second line, the init method has completed. It may not have completed successfully, but it will have completed.
The second form is a test. First the if statement calls the init method. If a valid object is returned then the test is true and then the next statement is executed. This is why you see init methods that return self when they are successful and nil when there is a problem; so that tests like these can be run to be sure that the object has been successfully initialised before continuing.
commands are executed in sequential order and not paralell
(dude, learn some basics ;)
As a rule, statements in C and Objective-C functions (and methods) are executed in sequence, in the order you write them. If you write one thing before another in a function, the first one must complete execution before the next one can execute.
The compiler may reorder statements if it believes that doing so will not change the behavior of the program (which it can predict very well in situations that don't involve concurrency), but this is an optimization. The C standard treats statements as being sequential, but allows compilers to implement this any way they like as long as the behavior of the actual program is the same as if the statements had been executed in the sequence in which they were written.
All this is a long way of saying: Your init method will complete before the calling method can resume execution.

Selectors in Objective-C?

First, I'm not sure I really understand what a selector is. From my understanding, it's the name of a method, and you can assign it to a class of type 'SEL' and then run methods such as respondToSelector to see if the receiver implements that method. Can someone offer up a better explanation?
Secondly, to this point, I have the following code:
NSString *thing = #"Hello, this is Craig";
SEL sel = #selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? #"YES" : #"NO");
NSLog (#"Responds to lowercaseString: %#", lower);
if ([thing respondsToSelector:sel]) //(lower == #"YES")
NSLog(#"lowercaseString is: %#", [thing lowercaseString]);
However, even though thing is clearly a kind of NSString, and should respond to lowercaseString, I cannot get the 'respondsToSelector' conditional to return "YES"...
You have to be very careful about the method names. In this case, the method name is just "lowercaseString", not "lowercaseString:" (note the absence of the colon). That's why you're getting NO returned, because NSString objects respond to the lowercaseString message but not the lowercaseString: message.
How do you know when to add a colon? You add a colon to the message name if you would add a colon when calling it, which happens if it takes one argument. If it takes zero arguments (as is the case with lowercaseString), then there is no colon. If it takes more than one argument, you have to add the extra argument names along with their colons, as in compare:options:range:locale:.
You can also look at the documentation and note the presence or absence of a trailing colon.
Selectors are an efficient way to reference methods directly in compiled code - the compiler is what actually assigns the value to a SEL.
Other have already covered the second part of your q, the ':' at the end matches a different signature than what you're looking for (in this case that signature doesn't exist).
That's because you want #selector(lowercaseString), not #selector(lowercaseString:). There's a subtle difference: the second one implies a parameter (note the colon at the end), but - [NSString lowercaseString] does not take a parameter.
In this case, the name of the selector is wrong. The colon here is part of the method signature; it means that the method takes one argument. I believe that you want
SEL sel = #selector(lowercaseString);
NSString's method is lowercaseString (0 arguments), not lowercaseString: (1 argument).
Don't think of the colon as part of the function name, think of it as a separator, if you don't have anything to separate (no value to go with the function) then you don't need it.
I'm not sure why but all this OO stuff seems to be foreign to Apple developers. I would strongly suggest grabbing Visual Studio Express and playing around with that too. Not because one is better than the other, just it's a good way to look at the design issues and ways of thinking.
Like
introspection = reflection
+ before functions/properties = static
- = instance level
It's always good to look at a problem in different ways and programming is the ultimate puzzle.
From my understanding of the Apple documentation, a selector represents the name of the method that you want to call. The nice thing about selectors is you can use them in cases where the exact method to be called varies. As a simple example, you can do something like:
SEL selec;
if (a == b) {
selec = #selector(method1)
}
else
{
selec = #selector(method2)
};
[self performSelector:selec];
As per apple docs:
https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html
A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn’t do anything. It simply identifies a method. The only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique. What makes a selector useful is that (in conjunction with the runtime) it acts like a dynamic function pointer that, for a given name, automatically points to the implementation of a method appropriate for whichever class it’s used with. Suppose you had a selector for the method run, and classes Dog, Athlete, and ComputerSimulation (each of which implemented a method run). The selector could be used with an instance of each of the classes to invoke its run method—even though the implementation might be different for each.
Example:
(lldb) breakpoint --set selector viewDidLoad
This will set a breakpoint on all viewDidLoad implementations in your app.
So selector is kind of a global identifier for a method.