I am using forward declaration in the calling Class.
.h file in ClassTwo
#class ClassOne
#property(nonatomic,retain) ClassOne *class_One;
.m file
#synthesize class_One;
Then i am trying to call this method in ClassOne
[self.class_One callingThisMethodFromClassTwo];
On the other hand if i create a shared instance in ClassOne and use it as a class method it works
[[ClassOne Shared] nowItWorks];
Sorry if this is a silly question i am very new
try to allocate class_One instance and add #import "ClassOne.h" to headers on top of your classtwo.m
self.class_One= [[ClassOne alloc]init];
[self.class_One callingThisMethodFromClassTwo];
If [self.class_One callingThisMethodFromClassTwo]; fails... this directly refers that
Either class_One is not alloc+init-ed.
Or callingThisMethodFromClassTwo is a private/protected method.
Or callingThisMethodFromClassTwo is a class method.
I am recommending you to use Protocol/Delegate for this issue.
You Should declare a delegate protocol for your class. An example of a delegate protocol and interface for class Foo might be in this way:
#protocol MyClassDelegate
// Required means if they want to use the delegate they
// have to implement it.
#required
// method that you want to call from another class.
- (void)taskComplete:(BOOL)complete;
#end
#interface MyClass : NSObject
{
// We don't know what kind of class is going to adopt us at
//compile time, that's why this is an id
id delegate;
}
#property (nonatomic, assign) id delegate;
(void)taskComplete;
(void)doSomeTask;
Suppose you have a complex project and don’t want to create lots of
linkages between your classes, in that case delegation like this is going to be your best way to implement. It’s like having function pointers ad callbacks, but the communication goes both ways easily. Time to adopt our protocol and actually use it in a class.
myClass = [[MyClass alloc] init];
// Very important. If we don't let myClass know who the delegate
// is we'll never get the protocol methods called to us.
[myClass setDelegate:self];
In this you can call method from another class. I hope this will help you.
Related
I m trying to passing values from second class to first class for that I am using protocol and delegate process. Whenever I run my program I am facing below Issue.
No Type or Protocol Named 'locateMeDelegate'
Viewcontroller A .h
#interface first : UIViewController < locateMeDelegate > { }
In my case the issue was caused by importing the delegate's header file to the delegator's class .h file. This seems to create a sort of vicious circle. As soon as I deleted the import statement of the delegate's header from the delegator's .h file, the error went away.
Tipically, if you intend your protocol to be used by other classes you must declare it in the header file like this:
// MyClass.h
#protocol MyProtocol;
#interface MyClass : NSObject
#end
#protocol MyProtocol
- (void) doSomething: (MyClass*) m;
#end
After you declare it, you should implement the methods of the protocol in the implementation file, which should conform to the protocol like this:
// MyClass.m
#implementation MyClass <MyProtocol>
pragma mark - MyProtocol methods
- (void) doSomething: (MyClass *)m {
// method body
}
#end
After these two steps you're ready to use you protocol in any class you desire. For example, let's say we want to pass data to MyClass from other class (e.g. OtherClass.h). You should declare in OtherClass.h a property so that we can refer to MyClass and execute the protocol. Something like this:
// OtherClass.h
#import MyClass.h
#interface OtherClass : NSObject
#property (weak) id<MyProtocol> delegate;
#end
You don't forget to import the header file where you declared your protocol, otherwise Xcode will prompt No Type or protocol named "MyProtocol"
id<MyProtocol> delegate; means you can set as the delegate of OtherClass any object (id) that conforms to the MyProtocol protocol (<MyProtocol>)
Now you can create an OtherClass object from MyClass and set its delegate property to self. Like this:
// MyClass.m
- (void)viewDidLoad() {
OtherClass *otherClass = [[OtherClass alloc] init];
otherClass.delegate = self;
}
It's possible to set the delegate to self because the delegate can be any object and MyClass conforms to MyProtocol.
I hope this can help. If you want to know more about protocols you can refer to this two websites:
Working with Protocols - Apple Documentation
Ry's Objective-C Tutorial (This one is easy to pick up)
I also faced the same issue and it seems the error is from Xcode itself. Please Try running on Physical device. This would solve the issue faced.
Normally I set up my delegates like normal:
#interface CAKGameViewController : UIViewController <CAKGameSceneDelegate>
then follow up in the CAKGameScene.h with
#protocol CAKGameSceneDelegate;
#interface CAKGameScene : SKScene <SKPhysicsContactDelegate>
...(properties, etc)
#protocol CAKGameSceneDelegate <NSObject>
#optional
- (void)getStarted;
#end
But as most of us know as a property you have to setup shop like this:
#property (nonatomic, weak, readwrite) id<CAKGameSceneDelegate> myDelegate;
My question is, I want to use the actual SKSceneDelegate (self.delegate, not (self.myDelegate) and go like this:
#interface CAKGameViewController : UIViewController <SKSceneDelegate>
Now this is fine and I can use self.delegate to reference the controller, but the problem is I can't seem to figure out how to customize the CAKGameViewController, i.e. setup the protocol further, or customize the protocol, for my methods and/or properties. :(
Any assistance would be helpful.
Thanks
I finally found a suitable workaround to use and assign the SKScene delegate. The trick is to cast (of course right)!?
You interface the GameViewController and conform to protocols
in CAKGameViewController.h
#interface CAKGameViewController : UIViewController
<SKSceneDelegate, CAKGameSceneDelegate>
in CAKGameScene.h
#protocol CAKGameSceneDelegate <NSObject>
// any #property;
// or - (void)methods;
#end
in CAKGameViewController.m you assign the delegate using self:
self.scene.delegate = self; //this is the Apple delegate property
then whenever you want to use
something = self.delegate.property; // <or>
[self.delegate method]; // from the CAKGameSceneDelegate protocol
you cast
something = ((id<CAKGameSceneDelegate>)self.delegate).property; // <or>
[((id<CAKGameSceneDelegate>)self.delegate) method]; // from non-apple protocol
what I did was just make a #define
#define delegateHelper ((id<CAKGameSceneDelegate>)self.delegate)
then I can:
something = delegateHelper.property;
[delegateHelper method];
I just figure if you are going to have a property called delegate, like most cocoa/objective-c objects do, to make things work, the delegate should be the delegate, you shouldn't have to use myDelegate, or something silly. delegateHelper may not be much better, but for me I can live with this workaround.
You can extend the original delegate in the protocol definition:
#protocol CAKGameSceneDelegate <SKSceneDelegate>
//extend SKSceneDelegate with new functions here
#end
Or in Swift:
protocol CAKGameSceneDelegate: SKSceneDelegate
{
//extend SKSceneDelegate with new functions here
}
You do not have to redefine delegate if you do it this way.
I am trying to figure out delegation in iOS. Basically, I have classA which contains methodA. I also have classB which I would like to call methodA from.
To be specific, I have a class called ViewControllerRootHome and class called ViewControllerRootHomeLeftPanel. The ViewControllerRootHome has a method in it called, movePanelToOriginalPosition I would like to call this method from the ViewControllerRootHomeLeftPanel class.
Any help would be greatly appreciated. Ohh forgot to mention I'm still using Objective-C for the project.
I'll give this an attempt.
Let's say you've got a ViewController called ViewControllerA, and another ViewController called ViewControllerB. We want to call a method inside A from B. How are we going to achieve this?
Simple. We will define a protocol inside B that A will comply to. Let me do that right here.
#import ...
#protocol myProtocol; // Declare Protocol
#interface ViewControllerB : UIViewController
#property (nonatomic, weak)id <myProtocol> myDelegate; // Create Delegate property
#end // Notice this is AFTER the #end of the #interface declaration
#protocol myProtocol <NSObject> // Define Protocol
-(void)doSomething;
#end
Okay, now you have defined a protocol called myProtocol that you wish to use inside ViewControllerA
Let us use it there. We will have to do several things: One, comply to the protocol. And two, set our current VC as it's delegate!
#import ...
#import "ViewControllerB" // IMPORT the VC with the Protocol
#interface ViewControllerA : UIViewController <myProtocol> // Conform to Protocl
#property (nonatomic)ViewControllerB *viewControllerB;
#end
Notice I've defined a property of type ViewControllerB. You will need to have a reference to ViewControllerB in some shape or form. This is usually easy to achieve because you normally create an instance of ViewControllerB from ViewControllerA. Otherwise it will need to be set externally or passed to ViewControllerA upon initialization and you set it as a property there.
Inside ViewControllerA.m, set ViewControllerA as it's delegate:
self.ViewControllerB.myDelegate = self;
Now, all you have to do is define the method from the protocol inside ViewController A so it can be called:
-(void)doSomething
{
...
}
This is all you need to do. However, please note that if you have TWO ViewControllers complying to each other's protocols, you will likely have to declare the protocols inside their own header files.
Edit: How to call the method.
If you want to call the method defined inside the protocol. You will do so inside ViewControllerB, like so:
if ([self.myDelegate respondsToSelector:#selector(doSomething)])
{
[self.myDelegate doSomething];
}
I've defined a protocol for my custom class, and now I want to give it a delegate. The class will not be instantiated, only used for its class methods. The delegate class, however, has been instantiated and assigned to a constant. If I was instantiating the class, I would let it refer to its delegate like this:
#property (weak) MyDelegateClass <MyProtocol> *delegate;
But because I'm not instantiating the class, I can't give it properties. So how do I refer to its delegate? A getter method? Something like this? Do I also need to define a setter?
+ (<MyProtocol>MyDelegateClass *)delegate;
What's the syntax here?
#interface NeverInstanciatedClass
+ (MyDelegateClass *) delegate;
+ setDelegate: (MyDelegateClass* <MyProtocol>) delegate;
#end
#implementation
static MyDelegateClass <MyProtocol> *_delegate;
+ (MyDelegateClass *) delegate {
return _delegate;
}
+ setDelegate: (MyDelegateClass* <MyProtocol>) delegate {
_delegate = delegate;
}
#end
(from scratch - never compiled nor syntax checked)
If you don't ARC then you may want to add some memory management. But as you use (weak) I assume you use ARC.
If you use protocols at all then you do not need to fully qualify MyDelegateClass* <MyProtocol> . id <MyProtoco> should do. I just did that because you did it in your sniplets.
As you access methods (and you should then access methods only) that are declared in the protocol, there is no need to even know what type of object it is. All you (and the compiler) need to know is that it implements the protocol.
I'm currently learning Obj-C and more specifically - protocols. I will need to make up a scenario here for my question to make sense.
First example (with a delegate).
I'm a UIView subclass which requests information from it's controller to be displayed (or rather how the information should be displayed). I declare a protocol and make a delegate reference object (or whatever it's called):
#property (nonatomic, weak) id <protocolName> dataSource;
My controller conforms to this protocol and implements the required method.
View sends messages to the Controller, and the Controller answers and everything is fine.
This as far as I know is delegation through protocols and I believe I understand it.
But let's consider another scenario.
I'm a class which is the brain for a simple level-based game. I say when to show the menu or when to start playing a game level. But I need to know when a level is completed.
Which means this class needs to be ready to receive messages from anyone that implements the protocol, for example from another class which is responsible for the current level. Now this is what I don't understand. How the protocol should look like and where/how to implement it?
Let me know if my question still doesn't make sense. Thanks!
Delegate is a one-to-on relationship method for sending message between entities.
If you want to receive the same message from different class, you can use NSNotification that is a one-to-many relationship.
Look at the NSNotificationCenter class, especially postNotification method (for sending messages) and addObserver method (used when received a notification)
EDIT :
Here's an example code for delegation.
Let's take your game level-based example. You have a LevelManager class and FirstLevel class. If you want the LevelManager to be notice when the FirstLevel ended, you have to declare a protocol in your FirstLevel class
// FirstLevel.h
#protocol SomeProtocol <NSObject>
-(void)levelDidEnd;
#end
#interface FirstLevel : NSObject
#property (nonatomic, weak) id<SomeProtocol> delegate;
#end
Then somewhere in your FirstLevel.m, call your protocol method when the level ended
// FirstLevel.m
- (void)playGame {
if ([player isDead]) {
[delegate levelDidEnd];
}
}
The next step is to implement your protocol to your LevelManager :
// LevelManager.h
#interface LevelManager : NSObject <SomeProtocol>
#property (strong, nonatomic) FirstLevel *firstLevel;
#end
And then, set your firstLevel.delegate and implement your protocol method
// LevelManager.h
- (void)viewDidLoad {
firstLevel.delegate = self;
}
- (void) didLevelEnd {
// do actions here like showing the menu
}
You still can go with delegation:
Let the level be a object with an delegate of type id<LevelDelegate>
#protocol LevelDelegate <NSObject>
-(void)completedLevel:(Level *)level;
#end
The BrainController conforms to LevelDelegate and creates all levels. for each level it set itself as delegate.
If a level recognizes it has finished, it calls [self.delegate completedLevel:self];.
The BrainController gets informed and does what ever is necessary.