29

I'm getting a warning about a semantic issue pertaining to passing a *const _strong to type id and cannot seem to fix it no matter what I change.

I have two views at the moment, and have written this code. In iPadSpeckViewController.m, here is the method that should switch between views:

-(IBAction) touchProducts {
    ProductsViewController *controller = [[ProductsViewController alloc]
            initWithNibName:@"Products" bundle:nil];
    controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    controller.delegate = self;
    [self presentModalViewController:controller animated:YES];
}

And for ProductsViewController.h:

@interface ProductsViewController : UIViewController {
    id<ProductsViewControllerDelegate> delegate;
}
@property(nonatomic, retain)
    IBOutlet id<ProductsViewControllerDelegate> delegate;

ProductsViewController.m contains:

@synthesize delegate;

But the views do not switch... Thoughts?

EDIT: Here is the exact warning, as it appears on the line "controller.delegate = self;" in iPadSpeckViewController.m:

/Developer/iPadSpeckApp/iPadSpeckApp/iPadSpeckAppViewController.m:17:27:{17:27-17:31}: warning: passing 'iPadSpeckAppViewController *const __strong' to parameter of incompatible type 'id<ProductsViewControllerDelegate>' [3]
Chris
  • 11,819
  • 19
  • 91
  • 145
  • Are you sure your ProductsViewController.h file "knows" about the ProductsViewControllerDelegate protocol? In other words, do you have an `#import "ProductsViewControllerDelegate.h"` statement at the beginning of your header file? – Leo Cassarani Jun 15 '11 at 22:20
  • Yep. Both iPadSpeckViewController.h and ProductsViewController.m have imported ProductsViewController.h – Chris Jun 15 '11 at 22:43
  • Please post the exact text of the error you are getting. Also, mark the line that the error occurs on, so we can see exactly what the compiler is complaining about. – Jeremy W. Sherman Jun 15 '11 at 22:46

3 Answers3

152

This warning is oddly worded, but it is actually just a way of telling you that the class of self (whatever that class is) fails to conform to the ProductsViewControllerDelegate protocol. To get rid of the warning, you have two choices:

  • Declare the class of self (whatever that class is), in its @interface statement, to conform to the protocol ProductsViewControllerDelegate:

    @interface MyClass : NSObject <ProductsViewControllerDelegate>;
    
  • Suppress the warning by changing this:

    controller.delegate = self;
    

    to this:

    controller.delegate = (id)self;
    

The delegate property is typed as id<ProductsViewControllerDelegate>. But self is not. Under ARC you must make the cast explicit, so that the types formally agree. (I believe this is so that ARC can make absolutely certain it has sufficient information to make correct memory management decisions.)

pkamb
  • 33,281
  • 23
  • 160
  • 191
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 4
    Thanks, this is an ARC issue I wasn't aware of. It fixed similar warnings when assigning self as a delegate. – Jason Moore Nov 10 '11 at 17:36
  • 1
    The (id)self helped for me, but the weird thing is for some other delegates this warning didn't pop up, even in the same implementation file. Anyways, now I know what to do if the warning arises! – Chang Hyun Park Feb 28 '12 at 15:03
  • 1
    @Heartinpiece - Look at the declaration for the delegate. Some delegates are simply typed id, so they can accept anything. Some delegates are typed as `id`, so the argument must adopt SomeProtocol (or you can cast away type checking by casting to `id`). – matt Feb 28 '12 at 15:28
0

Got the same error when i tried to set the delegate of a UINavigationController to an object that implemented the wrong protocol (UINavigationBarDelegate instead of UINavigationControllerDelegate). This might be a simple typo.

Christoph
  • 1,965
  • 16
  • 35
-1

If you only want to switch views, you might want to try the code below. It works for me.

ProductsViewController *controller = [[ProductsViewController alloc] initWithNibName:@"Products" bundle:nil];
[self.navigationController pushViewController:controller animated:YES];

I used that to have my main menu in my app switch over to the game.

If you want a special animation (I think I saw Cross Dissolve?), however, I have no idea. I will try digging through the documentation to see, and I will tell you what I find.

As for the "*const_string to type id", although I don't know what you are trying to do with your app, I think the problem is the id <ProductsViewControllerDelegate> delegate in your view controller.

Justin
  • 2,122
  • 3
  • 27
  • 47
  • I'm not using a navigationController (or just don't have one) so that it doesn't understand that – Chris Jun 15 '11 at 22:41