Theos instance method calling - ios

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>

Related

Calling method after checking its existence given error instead of warning

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.

+load method not getting invoked in iOS?

I am aware that +(void)load method gets called in ios even before the main function.
In my case it is only getting invoked with UIView and not with UITextView.
Are there any files that need to import ?
Does load method work only for certain set of class.
Please provide necessary input regarding conditions required in order to invoke +(void)load method in ios.
Getting invoked here :
#implementation UIView (SomeMethodSwizzling)
+(void)load{
}
#end
Not Getting inovked here .
#implementation UITextView (SomeMethodSwizzling)
+(void)load{
}
#end
Usual reason is that you're not actually linking the file. Most common cause is that you don't directly use anything declared in it (you sometimes need to pass -objc to the linker to fix that). Another cause is you just forgot to add the file to the target (I see that happen a lot).

How to tell what code is calling a method?

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?

SenTestingKit setUp and tearDown overrides get called twice

I am using KIF to test our iOS app. I am trying to make some tests that will go before and after my whole test sweet. I made a SenTestSuite category and overrode -setUp and -tearDown:
-(void)setUp
{
[tester loginCurrentVersion];
NSLog(#"setup");
}
-(void)tearDown
{
[tester logoutFromAnywhereIfNeeded];
NSLog(#"teardown");
}
These methods do get called, but my problem is that they both get called twice. I can't access any of the SenTestSuite.m methods. I am unsure why they are getting called twice. Why is it doing this and how can I solve this?
Thanks!!
Using a category to override a class's methods is really, really iffy. Instead, subclass SenTestCase and put your -setUp and -tearDown there. Then have your test classes inherit from it.
Since you are using KIF, your setUp and tearDown methods should be the beforeAll and afterAll. I also suggest you to take a look at the sample application and try to understand those tests.

IOS super keyword causes errors

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:.

Resources