i have a class MatchDayDataController , having a method pushIncompleteDataToServer.
from another class , SummaryVC.m i want to call pushIncompleteDataToServer in performSelectorInBackground.
Code:
MatchDayDataController *sharedDataController = [MatchDayDataController sharedDataController];
[self performSelectorInBackground:#selector([sharedDataController pushIncompleteDataToServer]) withObject:nil];
It shows some syntax error in performSelectorInBackground. What i missed here? pls guide.
[self performSelectorInBackground:#selector([sharedDataController pushIncompleteDataToServer]) withObject:nil];
This would make the code to search for the method in the same class
It should be:
[sharedDataController performSelectorInBackground:#selector(pushIncompleteDataToServer) withObject:nil];
which would call the method in the sharedDataController class
Also, in the method performSelectorInBackground: withObject: the withObject is for the parameters to be passed to the selector method. I this case, since there are no parameters, we pass nil.
Try this,
[sharedDataController performSelectorInBackground:#selector(pushIncompleteDataToServer) withObject:nil];
instead of
[self performSelectorInBackground:#selector([sharedDataController pushIncompleteDataToServer]) withObject:nil];
You need to replace self with sharedDataController.
[sharedDataController performSelectorInBackground:#selector(pushIncompleteDataToServer) withObject:nil];
The selector will be performed on the receiver of the performSelectorInBackground message, and self doesn't implement that method.
Related
In the case of method over riding in objective c how selector knows that which method needs to call via selector?
As we dont pass any arguments in slector section...
Ex:
in tmp.m file
There is 2 methods with different arguments
-(void)details
{
}
-(void)details:(NSDictionary *)result
{
}
And when m call another method with the use of selector as:
[mc detailstrac:[[NSUserDefaults standardUserDefaults] valueForKey:#"userID"] tracid:self.trac_id selector:#selector(details:)];
How selector knows to call which method !
I have checked that
-(void)details:(NSDictionary *)result
{
}
this method is called every time then what about
-(void)details
{
}
this ?
Selector will know on the basis how you call the method like from your example,
[mc detailstrac:[[NSUserDefaults standardUserDefaults] valueForKey:#"userID"] tracid:self.trac_id selector:#selector(details:)];
when you call #selector(details:) then the selector will call this method
-(void)details:(NSDictionary *)result { }
And When you call #selector(details) then the selector will call
-(void)details { }
The main difference here is #selector(details) and #selector(details:).
Hope you understand my point!
Happy Coding!
I have the following method:
- (void) someMethod
{
if ([super respondsToSelector:#selector(someMethod)])
{
[super performSelector:#selector(someMethod)
withObject:nil];
}
}
someMethod does not exist on superclass. as i understand, if there is no such method, runtime will ask the next responder in chain for such method till the NSObject class. And i was sure, that if statement will return NO.
Statement return YES. After that it performs selector without crash. As result - infinite recursion.
so, i have two questions:
Why [super respondsToSelector:#selector(someMethod)] returns YES ?
Why [super performSelector:#selector(someMethod) withObject:nil] does not crash with error 'does not responds to selector' ?
I think i've missed something essential.
Please, help.
Yes, you missed something essential as you suggest. From the documentation for respondsToSelector:
You cannot test whether an object inherits a method from its superclass by sending respondsToSelector: to the object using the super keyword. This method will still be testing the object as a whole, not just the superclass’s implementation. Therefore, sending respondsToSelector: to super is equivalent to sending it to self. Instead, you must invoke the NSObject class method instancesRespondToSelector: directly on the object’s superclass, as illustrated in the following code fragment.
if( [MySuperclass instancesRespondToSelector:#selector(aMethod)] )
{
// invoke the inherited method
[super aMethod];
}
HTH
I'm just learning iOS development but I have experience in C++ and I'm having an issue where my I call a method on an object but that object is not being called. Here is my code:
#implementation EXCoursesViewController{
EXNetworkingController *_networkController;
}
-(instancetype)initWithStyle: (UITableViewStyle)style{
self = [super initWithStyle: style];
if(self){
self.navigationItem.title = #"Title";
[_networkController createSession];
[self fetchFeed];
}
return self;
}
[_networkController createSession] doesn't seem to actually call the createSession method in the EXNetowrkingController I made. I'm not sure why this is happening. Any help would be greatly appreciated.
I'm not sure why this is happening.
Most likely, it's because _networkController is nil. It's apparently an instance variable, but you haven't given it a value at the point in -initWithStyle: where you're trying to send it a message.
To fix the problem, just create an EXNetworkingController instance and assign it to your ivar before using:
_networkController = [[EXNetworkingController alloc] init]; // or use the correct initializer
[_networkController createSession];
You are not doing the alloc and init for your EXNetworkingController. What i recommend is make your createSession method as public and call it. It can be called through the EXNetworkingController class name itself.
Do something like this:
+(void)createSession{
//Your createSession code goes here
}
You just have to replace the minus(-) which is in front of the -(void)createSession method with plus(+)
Then in your EXCoursesViewController class inside the initWithStyle replace [_networkController createSession]; with [EXCoursesViewController createSession];
And you no longer require to make an object of your EXCoursesViewController.
So you can remove EXNetworkingController *_networkController;
Hope this helps. Thanks.
I have function in Functions.h that I want to use from another h file.
I tried:
#import "Functions.h"
....
Functions *Func = [[Functions alloc]init];
[self performSelectorInBackground:#selector(?????????) withObject:nil];
Is it even possible?
If the methods are instance methods,
Functions *func = [[Functions alloc] init];
[func performSelectorInBackground:#selector(theMethodToRunInBackground) withObject:nil];
If they are class methods,
[Functions performSelectorInBackground:#selector(theMethodToRunInBackground) withObject:nil];
You should use Func instead of self
[Func performSelectorInBackground:#selector(function) withObject:nil];
Summary
I am trying to dynamically subclass objects to do some cleanup before dealloc. I add a subclass to the object and add my own dealloc method that does the cleanup and then calls [super dealloc]. This works for most cases but I am running into something strange when it happens to UIViewControllers. It seems some cleanup is not happening in dealloc because I am getting a crash when -hash is being sent to a deallocated view controller.
This happens when creating a view for a new view controller and it is growing some hash set in a class method of UIViewController. It seems to be a hash of view controllers for views because it is in a method +[UIViewController setViewController:forView:].
If I do not do the add my own dealloc method to the dynamic subclass everything is fine. Even if I only call [super dealloc] in my own version of dealloc it crashes the same way.
Does anyone have any idea what could be going wrong? Do I need to do something else other than calling [super dealloc] so that it still executes everything it should?
The Code
The dealloc method looks like this:
- (void)deallocWithRemoveAllAssociatedBindings {
[[BindingManager sharedInstance] removeAllBindingsAssociatedWithObject:self];
[super dealloc];
}
My dynamic swizzling method looks like this:
+ (void)createSubclassForObject:(id)object {
Class objectClass = object_getClass(object);
NSString *objectClassString = NSStringFromClass(objectClass);
NSString *subclassName = [NSString stringWithFormat:#"RemoveAllAssociatedBindings_%#", objectClassString];
Class subclass = objc_getClass([subclassName UTF8String]);
if (!subclass) {
subclass = objc_allocateClassPair(objectClass, [subclassName UTF8String], 0);
if (subclass) {
Method dealloc = class_getInstanceMethod(self, #selector(deallocWithRemoveAllAssociatedBindings));
class_addMethod(subclass, #selector(dealloc), method_getImplementation(dealloc), method_getTypeEncoding(dealloc));
[self addRemoveMethodToClass:subclass];
objc_registerClassPair(subclass);
}
}
if (!!subclass) {
object_setClass(object, subclass);
}
}
You can see the full code on github: https://github.com/drewag/property-bindings
you are never supposed to call dealloc on your own, thats apple's job. my suggestion would be to override the standard dealloc method and add what ever checks you need with an if statement to do your "custom dealloc" stuff. or you could just call your custom dealloc from inside dealloc just like how [super dealloc] is called... or just use ARC.