i am calling a method after checking its existence but it is keep giving the error. i am doing all this stuff many times but now it is giving error. any Help
if ([[self.navDashBoard.viewControllers lastObject] respondsToSelector:#selector(updateScreenForExtraOption)])
{
[[self.navDashBoard.viewControllers lastObject] updateScreenForExtraOption];
}
PLEASE see my updated image same thing works perfectly at the same class and other method does not. I had not make any Category or ViewController subclass that has refreshPage method in it.
usually what you see is this:
if ([[self.navDashBoard.viewControllers lastObject] respondsToSelector:#selector(updateScreenForExtraOption)])
{
[[self.navDashBoard.viewControllers lastObject] performSelector:#selector(updateScreenForExtraOption)];
}
This will give a warning but not a error while calling the method directly will. Or do it the way Paulw11 suggested and cast it to the right type.
i just fixed this issue by importing a class(UIViewController subclass) that has this method declare as public. even i am not using that class.
Related
I have this case where I just Call the init of Class I made this class is subclass of NSObject.
- (instancetype)initArray
{
self = [super init];
if (self) {
//Do Some Logic
}
return self;
}
This is my Call from the App Delegate
CategoryLoader *categoryLoader = [[CategoryLoader alloc]initArray];
Whats driving me crazy is that:
Although it returns nil it goes into the if condition
It doesn't return nil on other computer with other Xcode
Please note that both Xcode's are 6.3
Solutions i tried:
Cleaned Cache of Xcode
Deleted the class and created a new one
Reinstalled Xcode
Here is a Screenshot of whats happening:
Any suggestions why could it be returning nil from NSObject and what can i do next ?
Thank you
NSObject’s implementation of init should never return nil. This is documented in the NSObject Class Reference: although slightly confusing, the key part is
The init method defined in the NSObject class does no initialization; it simply returns self.
If you are observing it retuning nil, either something is not setup how you expect (perhaps the class isn’t a direct subclass of NSObject), or you are somehow interpreting the results incorrectly, or there is something wrong at another level. The fact that you observe different results on different machines suggests it might be at another level, like Xcode, the operating system, or the hardware. I can’t help much there; try rebooting.
Also, your method ought to be named init not initArray. This is not a requirement but a very strong convention. You can read about Object Initialization in Apple’s Concepts in Objective-C Programming
Ok. That was the problem:
The the scheme was on Release Mode. In this case the watch window displays nil in most of the objects. When I printed the value of self on NSLog it printed its value. The only difference between me and the other Xcode was the scheme.
So the solution is to edit the scheme of the project to be debug.
Thank you for your support
I have a method that's getting called in my iPhone app at an unexpected time, and I can't figure out what code is calling it. Is there any way to find this out from an Objective C method or an Xcode feature? Basically...
- (void)myMethod {
NSLog(#"who just called me?");
}
This method is called from lots of places in my code, so just searching for the method name doesn't narrow it down enough. I could temporarily add an argument to the method and then edit every call to the method to add a unique identifier as the argument, but that would require a lot of edits and then undoing all the edits when I'm done.
Ideally I would find the class and line number of the code that called this method. I don't need to use this info in the method, I just need it for debugging.
You can log the call stack to see from where the method got invoked
- (void)myMethod {
NSLog(#"who just called me? %#", [NSThread callStackSymbols]);
}
If you are running the app through Xcode then simply set a breakpoint in your myMethod and run the app. When the breakpoint is reached, the app will pause and the debugger will show you the stack trace leading to the method call. Then you can see exactly what it going on.
No need to log a stack trace. Look at in real time with the debugger.
Use NSThread +callStackSymbols — you can just log that directly.
Xcode give us a great feature "Break Point" you just need to put the break point in our method and you can see where the control reach.
This is the best I've come up with. Add some code to the method that crashes the app:
- (void)myMethod {
NSLog(#"who just called me?");
[self nonexistentMethod];
}
Then after the app crashes, type bt into the Xcode console to get a backtrace. From there I can see the last few methods that were called before this one. It's ugly but it works. Is there a better way?
I have searched for an answer to this and cannot find one.
How would I call an instance method in the same class I am hooking in my Theos tweak?
If I was using standard Xcode i would use the self method i.e.-
[self method:arg];
But in a theos tweak this says cannot find the method, even if i hook that method.
Example:
%hook classimhooking
-(void)methodimhooking
{
[classimhooking methodiwanttocall];
[self methodiwanttocall];
%orig;
}
-(void)methodiwanttocall
{
%orig;
}
%end
The methodiwanttocall is there and i can hook to it, just not call it.
I have tried adding a new method with %new and calling that but it is not found, i have tried the same with a delay, but it is not found.
I have tried defining a variable of my class and calling that but it doesn't work.
I can also see that you can grab iVars directly, but this doesn't work with methods.
Any ideas would be appreciated.
If you want to call a method on the object you just hooked, you can use performSelector (or performSelector:withObject: if it has an argument), which should be something like that:
[self performSelector:#selector(methodiwanttocall)];
Sorry to dig an old thread. I may have an idea about the issue here. In case anyone with the same issue comes across this.
The problem is that the compiler does not know there is such a method, even there is. The way to deal with it is to import the header at the top of the code.
#import <classimhooking>
I'm trying to close a superview by using this method [self.superview buttonPressedClose];
I have already implemented that method in my superview, and everything works.
But it gives me an alert "UIView may not respond to 'buttonPressedClose'" during compile.
If I change it to the following line, it doesn't give me the alert, but is this the correct way to do it?
if ([self.superview respondsToSelector:#selector(buttonPressedClose)]) {
[self.superview performSelector:#selector(buttonPressedClose) withObject:nil afterDelay:0.0];
}
Thanks.
**Edited typo..
Is this a typo in question or in your code?
if ([self.superview respondsToSelector:#selector(buttonPressedClose)]) {
// vv here
[self.superview performSelector:#selector(buttonPressedCLose) withObject:nil afterDelay:0.0];
}
In general, self.superview returns an object of type UIView, and your buttonPressedClose is a custom selector that's not implemented in UIView. That's why you're getting a warning.
You might want to cast self.superview to your desired type, e.g.:
[(MyView *)self.superview buttonPressedClose];
or make it even more mysterious and cast to id - compiler doesn't check for selectors presence then:
[(id)self.superview buttonPressedClose];
That said, all of the above solutions are a bit smelly.
One very important thing regarding performSelector: with zero delay - it doesn't execute the selector in place, but rather it posts selector execution to thread's run loop and executes it when control returns to the run loop (i.e. when call stack is empty). So in normal situations you wouldn't like to use it.
"is this the correct way to do it?"
No, there is no reason to do it this way. afterDelay:0 is only used if you want to not execute it immediately. If you want to execute it immediately, then you should use performSelector: without afterDelay:.
But using performSelector: directly like this has no benefit. It is equivalent to, and is a more convoluted way of, calling the method directly. The warning you are getting is purely a static type-checking issue. The type (UIView *) is not guaranteed to have that method. You need to cast it to the expected view type that supports the method, or cast it to id to turn off checking of methods. When you used performSelector:, that also skirts around static type checking of methods, so it is strictly no better than casting it to id and then calling it.
I'm updating the code in an app I didn't write while at the same time basically teaching myself objective C so am a beginner with this stuff.
I have a class called TableViewController and in it I have a method that is fired once a JSON feed successfully gets some data. This method is called:
- (void)JSONFetch:(MYJSONFetch *)fetch didDownloadCollection:(id)collection
{
//CODE HERE
}
I have a bunch of other classes that inherit from this class and in turn they call their own version of this method and add their own bits of functionality to the mix.
So for example I have a class called CategoryViewController that has this method defined in it:
- (void)JSONFetch:(MYJSONFetch *)fetch didDownloadCollection:(id)collection
{
[super didDownloadCollection:collection];
}
Notice the SUPER call there, ideally it should be able to access all the code in the parent's method and its own code as well.
In the .h file on the category controller I have this:
#import "MYTableViewController.h"
#interface MYCategoryViewController : MYTableViewController
{
//code here
}
So it should be able to 'see' the other code, but I get this error on the SUPER line:
Instance method '-didDownloadCollection' not found (return type defaults to 'id')
Which presumably means it actually can't see the parent method. It's not set as private as far as I can tell, the .h explicitly mentions the inheritance and other method calls happily bounce back and forth between the two.
So, something I've done has borken this good and I've no idea what. I've an inkling it must be in the MYJSONFetch code, but am not sure.
Anyone shed any light on this, hours spent trying to figure out why it can't see the parent method.
The method is
- (void)JSONFetch:(MYJSONFetch *)fetch didDownloadCollection:(id)collection
So you have to call
[super JSONFetch:fetch didDownloadCollection:collection];
Thats because the method is looks like this JSONFetch:didDownloadCollection: instead of this didDownloadCollection:.