views:

182

answers:

3

Hello,

First time working with protocols and it is not working but no errors either...

I have defined and implemented a protocoll in a delegate (BlockPopViewController). Then I try to access it from a UIViewController (BoardViewController) whose view has been added to the delegate as a subview.

The result is that my request to the protocol's method is not creating any errors, but the method is not triggered either. Would be most appreciated if someone has an idea. Thanks in advance!

BlockPopViewController.h

#import "DirectionViewController.h"

@class BoardViewController;

@protocol BVCProtocol

- (void)testing;

@end

@interface BlockPopViewController : UIViewController <BVCProtocol> {}

-(void)testing;

@end

BlockPopViewController.m

@implementation BlockPopViewController

-(void)testing{
    NSLog(@"Testing in delegate BlockPopViewController"); 
}

@end

BoardViewController.h

@class BoardView; //This I cannot import, I think this should be ok instead. Probably cyclic import...
@class Bric;  //This I cannot import, I think this should be ok instead. Probably cyclic import...


@protocol BVCProtocol;

@interface BoardViewController : UIViewController {

}

@property(nonatomic, assign) id <BVCProtocol> blockPopViewController;

@end

BoardViewController.m

#import "BlockPopViewController.h"
#import "BoardViewController.h"

@implementation BoardViewController

@synthesize blockPopViewController;

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event{

   NSLog(@"INSIDE TOUCHESENDED");
   [[self blockPopViewController] testing];

}
+1  A: 

You are missing a declaration of your BlockPopViewController class which says that BlockPopViewController implements the BVCProtocol protocol.

You should also have your implementation of BVCProtocol derive NSObject in order to get proper memory management behavior. Additionally, you should derive all your protocols from the NSObject protocol in order to prevent compiler warnings when you use NSObject messages on instances of your protocol implementation.

In BlockPopViewController.h you need:

@protocol BVCProtocol <NSObject>
- (void) testing;
@end


@interface BlockPopViewController : UIViewController <BVCProtocol>
@end

In BoardViewController.h you must also #import "BlockPopViewController.h". Otherwise, the compiler won't know anything about the fact that BlockPopViewController is implementing BVCProtocol nor anything about BVCProtocol to begin with.

It would be more logical to declare a protocol in its own .h file and to import that in .h file declaring an implementation of the protocol.

You might find this little tutorial helpful.

VoidPointer
Thanks for you quick repy. But when doing "BlockPopViewController : NSObject <BVCProtocol>" I will get errors due to BlockPopViewController is not inheriting UIViewController properly... At the end, all objects inherit from NSObject, so is this really necessary? I am new to Ojbective-C so perhaps I missed something fundamental.
Nicsoft
I checked out the tutorial; I assume it should be "@interface BlockPopViewController : UIViewController <BVCProtocol>" instead. I did as you described, still no method triggered, and still no errors... Also, according to the tutorial, i defined "id <BVCProtocol> blockPopViewController;" in my BoardViewController as well (before I did only "id blockPopViewController;", which I forgot to include above). No difference in behaviour though.
Nicsoft
Sorry, I missed that BlockPopViewController was to derive UIViewController - I updated the answer.
VoidPointer
Classes do not automatically inherit NSObject. All framework classes (like UIViewController) do, but they do so explicitly. If you create a class that does not derive a class that already derives from NSObject you need to explicitly derive from NSObject.
VoidPointer
You're right. Since xCode automaticaly make sure my custom objects inherit from NSObject, my simple mind has adopted this as a rule that I don't need to inherit it (which of course is a misconception).
Nicsoft
A: 

Declare protocol outside @interface ... @end context

@protocol BVCProtocol
- (void) testing;
@end


@interface BlockPopViewController : UIViewController <BVCProtocol>
//...
@end
vaddieg
Sorry, I forgot that row above, it's now edited. I did define the protocol outside @interface all the time. Didn't have to change that....
Nicsoft
Additional information: If doing: "if ([blockPopViewController conformsToProtocol:@protocol(BVCProtocol)]) {" it returns NO... But then I don't understand why it doesn't...?Also, I did change the interface declaration in BoardViewController to "@interface BoardViewController : UIViewController <BVCProtocol>", and now I get the warning that "No definition of protocol "BVCProtocol" is found. I get the feeling that the problem has to do with finding the protocol-definition in some way... But I don't see why?
Nicsoft
You need to #import the .h-file declaring BVCProtocol in the .h-file that declares BoardViewController. Then you need to #import the .h-file that declares BoardViewController in the .m-file that implements BoardViewController.
VoidPointer
A: 

I think the problem I had was that I didn't create an instance of "BlockPopViewController". I changed my solution to not use protocols since it seems like overkill for me. I do have full controll of all involved classes and don't get any benefits using protocols. I do however think that this is what caused it to not work. If there is a reason for using protocols in this kind of situation which I am not aware of, pleas fill me in...

Nicsoft