xCode says the object might not respond to selector while I'm checking for it - objective-c

I have the following code:
if([node respondsToSelector:#selector(setOpacity:)])
[node setOpacity:127];
I know node might not respond to setOpacity: so I check for it, but xCode still warns against it. is there any way of safely calling the selector without xCode complaining? the warning is:
/path/file.mm:79: warning: 'CCNode' may not respond to '-setOpacity:'

if([someIndexes respondsToSelector:#selector(setOpacity:)])
[(id)someIndexes setOpacity:127];

Related

Work around of "No known instance method for selector" error for id type

My iPhone app has a login view controller to pop up whenever it is necessary to login. After the user loged in, I have this:
if ([self.presentingViewController respondsToSelector:#selector(userDidLogin)]) {
[((id)self.presentingViewController) userDidLogin];
} else {
[self.presentingViewController dismissModalViewControllerAnimated:YES];
}
However, the compiler kept complaining about "No known instance method for selector userDidLogin". Then I added an instance method named userDidLogin for the login view controller, which was of course not self.presentingViewController, then the build succeeded.
This workaround feels unreasonable to me. Is it a bug in Xcode or intended behavior? Is it is the latter, what is the rationale?
The compiler needs to know the return type of the userDidLogin selector so that it can generate correct code:
If the message returns a struct, the compiler may need to generate a call to objc_msgSend_stret. (Source: Greg Parker's blog.)
If the message returns a floating-point number, the compiler needs (on some platforms) to generate a call to objc_msgSend_fpret. (Source: Greg Parker's blog.)
Otherwise, the compiler needs to generate a call to objc_msgSend.
The userDidLogin selector has no arguments, but if the selector did have arguments, the compiler would also need to know the declared argument types so it could pass the arguments correctly.
Additionally, if you're using ARC, the compiler needs to know the return type and ownership annotations of the selector so that it can generate a release of the return value if appropriate.
The usual way to handle this is just to #import the header file of the class that declares the userDidLogin message. As long as the compiler has seen the selector declared somewhere, it won't complain about sending it to an id.

Debugger lldb says my object is nil when is not ?

Recently I upgraded my project settings in Xcode 4.3 and now I use the latest llvm debugger: lldb
However (sometimes) I have the impression the debugger is not giving me the correct info? Could this be possible?
For example, The debugger says _documentsItem is nil (both in in the console and when mouse-over-ing the ivar). But I know it's NOT, that is why I can see it (an UIBarButtonItem) and more important that is why the app stopped at the shown breakpoint)
if (_documentsItem) { ...
In fact most of my properties return nil too :(
Is there a way I make sure the debugger is doing fine?
I've met similar issues in Xcode 4.3. And press "Option" while click "run" and changed it back to stable gdb.
It is definitely nil.
Look at the address that its been allocated. 0x00000 is nil.
This is a bug with XCode, which still hasn't been resolved, as of 4.3.2. Switch back to GDB, even if XCode complains about your project settings.
For view property value, use
"po self.yourproperty"

Why does this Objective C call appear to hang?

A friend of mine discovered some strange behaviour with NSDictionary, and I'm curious as to why it happens. Consider the following code:
NSDictionary *dict = [[NSDictionary alloc] init];
// Oops, we can't mutate an NSDictionary
[dict setObject:[[NSNull alloc] init] forKey:#"test"];
NSLog(#"Set");
The code produces a warning upon compilation that "'NSDictionary' may not respond to 'setObject:forKey:'". That's all well and good, and if you run it anyway, you'll get this output in the console:
-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object
Again, exactly what you'd expect to happen. However, at this point the app does not crash or terminate due to an uncaught exception. The setObject:forKey: method simply never returns, and the app appears to hang; the following NSLog is never executed. If you try to step over or into the method using GDB, debugging just seems to end, but without any explicit error message. The app continues to run, but the debugger provides no clue as to where in the code the execution is "stuck."
What's going on here? What is the app actually doing in this case, and why doesn't it crash with an NSInternalInconsistencyException or something of the like?
Edit: For those who have asked, I'm running XCode 4.1 on OS X Lion (10.7.2), building with "Apple LLVM compiler 2.1." I'm using all of the default settings you get with a new Cocoa project in XCode 4. I experience the same non-crashing behaviour regardless of whether I debug the program or just "Run" it. Changing from Debug building to Release building makes no difference. I can even locate the .app file manually in Finder and double click on it to execute it outside of XCode, and it still does not crash.
Exceptions do not crash AppKit programs. NSApplication installs a default exception handler that catches exceptions that your code doesn't. Then you just go back into the runloop as normal.
Lots of apps exhibit this behaviour. It's a common cause of inexplicable blank views/windows. If an exception happens before a view manages to finish drawing, the view will be blank, but the app won't crash. Exceptions only cause a crash if you deliberately change the default exception handler to crash.

Problems implementing Growl

I am trying to include Growl support in an app, but it is crashing when setting the delegate. As per http://growl.info/documentation/developer/implementing-growl.php , I am just setting the delegate like so [GrowlApplicationBridge setGrowlDelegate:#""]; as I am only needing Growl for basic usage, but upon running it crashes.
Xcode shows the following warning on that line:
Semantic Issue: Incompatible pointer types sending 'NSString *' to parameter of type 'NSObject<GrowlApplicationBridgeDelegate> *'
Any ideas on how to resolve this?
Fixed: I set added to my header file and set the delegate to self
Fixed 2: It actually wasn't that, it was the version of growl sdk I was using having a bug in it, fixed with v1.2.2 of growl.
Don't set the delegate (leave out that line) and you should be fine.
If you need a delegate that you have to set it to an instance of a class that implements the protocol.
Cast it to an untyped object to eliminate the warning.
[GrowlApplicationBridge setGrowlDelegate:(id)#""];
It was the version of growl sdk I was using having a bug in it, fixed with v1.2.2 of growl.

What does the “unrecognized selector sent to instance” error mean?

I am getting a crash in my app due to the following error:
-[NSCFString count]: unrecognized selector sent to instance 0x612b060
Can anybody tell me what does it mean and how can i find the line in my code with reference 0x612b060
You are calling count method on an object (probably a collection e.g array, dictionary, or set) which is released or has not been initialized yet.
You are sending message "count" on NSCFString, means, calling "count" method on NSString datatype.
To find the code, you can use Stack trace, but I am sure what you are doing is:
Assign NSString data on NSArray or (Array datatype) and trying to count.
Most likely this happens because you have a collection object (eg NSArray, NSDictionary) that you do not retain properly.
Try to use NSZombies to find the object that got released.
Right-Click on the executable in the Executables group in Xcode. Select Get Info
Select Arguments tab.
In Variables to be set in the environment create a variable called NSZombieEnabled and set its value to YES. Don't forget to activate it.
Turn on breakpoints and run your code.
the debugger will point you to the object that gets released to early.
After you've done debugging this problem you should deactivate NSZombies. NSZombies won't release any memory, it just marks the objects as released.
So you will end up in a memory warning sooner or later.
You can simply remove the checkmark in front of it to deactivate NSZombies.
Did you mean to call length on your string?
Maybe someone will need this:
When I had this kind of problem I used:
[ myarray retain];
after
myarray = [NSArray arrayWithObjects: ...];
and it worked. I think it was because my array destroying itself too early.
But I don' t know how I can now release this object?
Just [myarray autorelease]? Is there something opposite to retain ?
A practical example:
Sometimes, there is a practical difference which I don't understand clearly yet. valueForKey didn't work in SOGo-3.1.4's code trying to call an unavailable "method" ASProtocolVersion on the context object:
`EXCEPTION: <NSException: 0x55f43f93e4d0> NAME:NSInvalidArgumentException REASON:-[WOContext ASProtocolVersion]: unrecognized selector sent to instance
whereas objectForKey works (and is the usual way to query the context object elesewhere in the code).
See https://github.com/inverse-inc/sogo/pull/217/files