i am declare the protocol in one UIView class i want to implement the protocol method in another UIView class. but the protocol method does not call what can i do. Any one Help me
Did you call the delegate function in UploadView?
Also, since it is optional function, you have to check if the delegate response to the function before calling it.
- (void)yourFunction {
...
if ([self.delegate respondsToSelector:#selector(takeAnotherPhoto:)]) {
[delegate takeAnotherPhoto:self];
}
...
}
Related
I'm trying to tell if there is a way to determine if a class is conforming to a specific (optional) protocol method at runtime. Is there a way to check for this? Don't want to send a call to a nonexistent delegate method implementation in the delegate class.
BOOL isProtocolConformed=[YourClass conformsToProtocol:#protocol(YourProtocol)];
BOOL isSelectorResponse=[yourObject respondsToSelector:#selector(yourMethod)];
if(isProtocolConformed && isSelectorResponse){
//do your stuff
}
if ([self.delegate respondsToSelector:#selector(protocolMethod)])
{
[self.delegate protocolMethod];
}
From documentation:
respondsToSelector:
Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message.
just had a noob question. I'm trying to understand the difference between calling self and super. Now I understand inheritance and other fundamental OOP concepts, but the idea of self and super is still not clear to me. I'll illustrate my question with an example.
So the the below code performs a segue when the phone is tilted upside-down. I understand that "Scene2ViewController" is a subclass of "UIViewController" and so "Scene2ViewController" inherits all of UIViewController's methods. And so below I'm calling the method performSegueWithIdentifier with the receiver of the message being self. Now when I change "self" to "super" the code still executes the same way. Isn't calling super the same as calling self? If someone could explain this to me it would be appreciated, thanks.
//Scene2ViewController.m
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[self performSegueWithIdentifier:#"SegueToScene1" sender:self];
}
return (interfaceOrientation ==
UIInterfaceOrientationPortrait);
}
self and super actually both point to the same object. super is a keyword that tells the compiler to generate instructions that start the search for a method definition in the super class rather than in the current class.
#interface A : NSObject {}
- (void)foo;
#end
#implementation A
- (void)foo {
NSLog(#"A's foo!");
}
#end
#interface B : A
#end
#implementation B
- (void)foo {
NSLog(#"B's foo!");
}
#end
//...somewhere in a method of class B...
[self foo]; // prints "B's foo" in the console
[super foo]; // prints "A's foo" in the console
If we assume, per the comment, that the last lines are somewhere in a method of B, then self points to some instance of B. super also points to that same instance of B. But when you use self to call foo, the search for an implementation of foo starts with class B. When you use super, the search for a foo starts with B's superclass, A.
super is especially handy when you want to preserve the inherited behavior, but add something on. So, we could have B's implementation of foo call A's version using [super foo]. Without super there'd be no way to call the inherited method, and calling foo from the overridden method would result in infinite recursion.
When you call a method of self (or rather send a message to self in Objective-C terms) the runtime will search for an implementation of that method in the inheritance hierarchy, starting with self, going up to NSObject. So if self implemented that method, it will be executed. If not, the super class will be checked and so on.
Sending the message to super is very similar, with the exception that the runtime will start looking for an implementation in super and skip self.
Well sometimes, in a subclass, you might override a function that was already defined in the parent class. Frequently this happens in the init function. So if you need to call the parent class's init function you call super. If you need the subclass' function you call self. If only the parent has the function declared then Self and super act the same. But if only the subclass has the declaration then you cannot call the function from super.
I am having a problem I am working on a class which is subclass of UITextField.
Which will be used in many classes further.
But I don't want to let user to use it's delegate methods in any way.
Is there any way to do this ?
Override setDelegate: so that it throws an exception or logs an instruction on what to do. That way your API users will know what's actually going on.
-(void) setDelegate: (id <UITextFieldDelegate>) delegate
{
NSLog(#"*** Use the blocks API instead of calling %s", __PRETTY_FUNCTION__);
[self doesNotRecognizeSelector: _cmd];
}
Override the -setDelegate: method such that it never actually sets a delegate. You can just provide an empty method that fails to call super:
-(void) setDelegate:(id<UITextFieldDelegate>) delegate
{
// this method intentionally empty to prevent a delegate from ever being set
}
I am having some trouble figuring out hour to accurately override a method in one of my subclasses.
I have subclass (ClassB) of another customclass (ClassA):
#interface ClassB : ClassA {
}
and within ClassA, there is a method called:
-(void)methodName;
which fires correctly.
However, I need this method to fire in ClassB.
I've tried implementing (in ClassB):
-(void)methodName {
[super methodName];
}
but it still won't fire in ClassB.
How can I override methodName so that it will fire in ClassB?
You just add your custom code in methodName in classB :
- (void)methodName
{
// custom code
// call through to parent class implementation, if you want
[super methodName];
}
First, make sure your init method creates a ClassB object and not a ClassA (or something else) object.
Then, if you want to create a completely different classB (void)methodName: method than the one found in classA, this is the way to go:
Super is the superclass. By calling [super methodName] you're asking ClassA to execute it's own methodName.
If you want to completely override methodName from classA, just don't call super.
So, basically, in your classB's implementation of methodName:
-(void)methodName {
// Remove [super methodName]
// Insert the code you want for methodName in ClassB
}
Feel free to read Messages to self and super in Apple's The Objective-C Programming Language document.
By writing:
-(void)methodName {
[super methodName];
}
You tell the compiler: When executing methodName of Class B, call methodName of its superclass (Class A). So if you want Class B to do something different you have to write code that results in a different behavior. Like this:
-(void)methodName {
NSLog(#"Hello, world!");
}
Now by calling methodName of Class B "Hello, world!" will be printed on the console.
-(void)methodName {
[super methodName];
}
Wanna call methodName (in ClassB), just remove [super method] then you can fire it.
Cause super is call back to ClassA
Although this question is too old, but there are sill some learners as every expert was,
The following is quoted from Apple documentation.
"The new method must have the same return type and take the same number and type of parameters as the method you are overriding."
full answer can be found in Apple method overriding documentation
Hope this helps someone.
i created a delegate for a class
#protocol gameDelegate <NSObject>
#optional
-(void)gameStarted;
#required
#end
now in my game object i called this method:
[self.delegate gameStarted];
so now, if i initiate this object anywhere and set the delegate everything works fine until the gameStated gets called, because its not implemented in the main object where the game object is created (because its optional).
i tried some variations of this
if(![self.delegate respondsToSelector: #selector(gameStarted)]) {
//[self.delegate gameStarted];
}
but this is not working for me.
any ideas how to make this "really" optional?
thanks in advance
Omit the negation from your if statement:
if ([self.delegate respondsToSelector:#selector(gameStarted)]) {
...
}
To accomplish this in swift, I recommend the following:
#objc protocol MyDelegate {
optional func optionalMethod()
}
class MyClass : MyDelegate {
// optionalMethod() does not have to be declared
}
Then to call the optional on your delegate object, simple use if delegate.optionalMethod?(){}
Checking if a delegate implements an optional method and then calling it is such a common pattern that I use a preprocessor macro SAFE_CALL that checks respondToSelector: and then calls the method.
The macro is:
#define SAFE_CALL(obj,method) \
([obj respondsToSelector:#selector(method)] ? [obj method] : nil)
and it is used like this:
SAFE_CALL(sourceDelegate, refresh)
// or
NSString *response = SAFE_CALL(object, responseValue)
Note this version works only with methods with no parameters.
Originally it was implemented as a C function, but that causes warnings with performSelector leaks when using ARC. As a preprocessor macro it works exactly as expected.