Warning when setting a delegate - iphone

I'm trying to pass data back with the segue, and am following this answer: How to Pass information Back in iOS when reversing a Segue?
However when I try to put this line in:
#property (nonatomic) id<MyDataDelegate> delegate;
I get the following warning:
And when I try to put to the first view controller like this:
#interface ContainerViewController : UIViewController <MyDataDelegate>
I get the error "Cannot find protocol declaration for 'MyDataDelegate' " and I did include the other header file...

From the error message it looks like you are adding the property to a subclass of UIPageViewController. But UIPageViewController already has a delegate property of a different type.
You therefore need to either rename your property to something else, or declare MyDataDelegate to conform to UIPageViewControllerDelegate so that your property redeclaration is compatible with the base class version:
#protocol MyDataDelegate <UIPageViewControllerDelegate>
...
#end
You also need to declare your property with the weak attribute.

Related

In interface file: when to use forward declaration for custom class as opposed to just including its header?

I have subclass of UIViewController called FullScreenViewController which has a property of type ImageScrollView which is subclassed UIScrollView object. The implementation and interface look as follows:
FullScreenViewController.h
#import <UIKit/UIKit.h>
#class ImageScrollView;
#interface FullScreenViewController : UIViewController
{
ImageScrollView *_scrollView;
}
#property(nonatomic, retain) ImageScrollView *scrollView;
#end
FullScreenViewController.m
#import "FullScreenViewController.h"
#import "ImageScrollView.h"
#implementation FullScreenViewController
#synthesize scrollView = _scrollView;
...
#end
now I subclass FullScreenViewController, and I try to access any properties from the ImageScrollView property and I keep getting the error message: "Property cannot be found". When I add ImageScrollView.h to the subclass, it works, but I'm not understanding this. I've already added ImageScrollView.h in FullScreenViewController, why should I have to add it again?
UPDATE: Rather than using a forward class declaration, I've included ImageScrollView.h in FullScreenViewController.h. I'm a little confused as to why I've ever use a forward declaration versus just including the .h file?
The reason you need to add it is you only have a #class declaration in your FullScreenViewController.h file. That only declares variable of type ImageScrollView* as pointers to object of class ImageScrollView. It does not give you access to the properties of ImageScrollView. To get access to methods and properties specific to ImageScrollView, you need to include the #interface declaration of ImageScrollView, which I assume is in your ImageScrollView.h file.
Given the header:
#interface FullScreenViewController : UIViewController
{
ImageScrollView *_scrollView;
}
#property(nonatomic, retain) ImageScrollView *scrollView;
#end
a forward declaration #class ImageScrollView is all that's needed. This tells the compiler that there is an objc class named ImageScrollView.
Of course, with a forward declaration, the interface is not visible where you need to use it unless you also #import ImageScrollView where you use it.
now I subclass FullScreenViewController, and I try to access any properties from the ImageScrollView property and I keep getting the error message: "Property cannot be found". When I add ImageScrollView.h to the subclass, it works, but I'm not understanding this. I've already added ImageScrollView.h in FullScreenViewController, why should I have to add it again?
ImageScrollView's declaration is not visible to the subclass FullScreenViewControllerSubclass. ImageScrollView.h is visible only where #imported. FullScreenViewController.m is not visible to FullScreenViewControllerSubclass.m. Therefore, you must write another #import in FullScreenViewControllerSubclass.m to use ImageScrollView there.
UPDATE: Rather than using a forward class declaration, I've included ImageScrollView.h in FullScreenViewController.h. I'm a little confused as to why I've ever use a forward declaration versus just including the .h file?
Use forwards for fast build times and sane, controlled dependency structures. This is a very time consuming problem to undo. And this problem gets much worse as the size of your programs and libraries increase:
Would you prefer a change to a header in a medium sized project to require recompilation of 50 sources with an average preprocessed input of 150,000 lines per translation, or would you favor that change to affect 6 sources with an average preprocessed input of 40,000 lines per translation? The difference here is that small change takes the incremental rebuild from seconds to minutes to complete, depending on how you have structured your dependencies and imports.
Have you tried accessing it using the alias _scrollView or scrollView.you should access it using _scrollView and see if u have imported the file in .m or .h as #class won't suffice.

Can't determine calling class's variable's value using XCode

Here's what I'm looking to do. I have a UITableViewController that has a variable, bInternetOK, that I need to reference from a class that the UITableViewController instantiates. This way, the class can make sure the internet is available before it tries to do some work. In the .h of the UITableViewController, I've defined the variable like this:
Boolean bInternetOK;
And I've set a property like so:
#property (nonatomic) Boolean bInternetOK;
In the .m of the UITableViewController, I've synthesised the variable like this:
#synthesize bInternetOK;
I instantiate the class (TheNetworkClass) like this and then call the function to start the work:
TheNetworkClass *TheNetworks = [[TheNetworkClass alloc]init];
[TheNetworks StartUpTheWork];
Inside of the TheNetworkClass class, I'm trying to reference the variable bInternetOK that is in the UITableViewController class. How do I do this?
Thanks!
You could give the instance of your TheNetworkClass object a reference to your table view controller instance when you create it.
Or you could just give your TheNetworkClass object the boolean, if it only checks it on creation.
Or, if the table view can be accessed as a property on your application delegate, you can get the application delegate with [UIApplication sharedApplication].delegate and then access that property to get to the table view.

xcode: property 'title' 'copy' attribute does not match super class 'UIViewController' property

Hi I'm currently getting this error message. and by the love of banana, I cannot figure out what I am not doing right.
Its just an
IBOutlet UILabel *title;
and
#property(nonatomic, retain) IBOutlet UILabel *title;
I've made which is connected to my xib file connected to a UILabel because I dynamically change the title during run time.
Classes/../taskViewController.h:44: warning: property 'title' 'copy' attribute does not match super class 'UIViewController' property
I dont understand what it means.
Normally i am able to get rid of warning messages. But this one... I dont have a clue whats going on.
Can someone please guide me and explain what is happening here.
Your problem is that UIViewController already defines a title property and you are using a different memory manangement option than it does. To fix this, change the name of your property. ex: #property (nonatomic, copy) UILabel *titleLabel;. If you want the instance variable to have the same name, and you use #synthesize, use #synthesize titleLabel=title;.
As an aside, why are you copying a UILabel? Normally you would use retain so that it is the same object.
It means:
you have a subclass of UIViewController
it contains a property named "title"
you have declared the property with the "copy" attribute
the parent class (UIViewController) already has "title" property with a conflicting definition (i.e., not "copy")
Well i want to just clarify that title is a predefined object in the UIViewController so you cannot create your own objects with that same name, change the with some thing else and see that it wont give you that error.

Do I need to declare a private variable for an IBOutlet* property?

Let's say I have a simple view controller with one UITableView property:
#interface MyViewController : UIViewController {
UITableView *tv; // <-- DO I NEED THIS??
}
#property (nonatomic, retain) IBOutlet UITableView *tv;
#end
Do I actually need to declare the UITableView *tv ? I've found that even if I don't declare it (and simply #synthesize the property), everything works fine. Yet, lots of code samples explicitly declare the variable. I'm not sure what the benefit of declaring it (or the harm of not declaring it) is.
In Objective-C 2.0, the compiler will synthesize the storage for you as well as the accessors. That didn't used to be the case, hence all the examples where people explicitly declare the ivar.
No you do not have to declare it, synthesize will take care of dynamically injecting the code at compile time. You will on the other hand not be able to inspect the variable directly in Xcode if you do not declare it, that's the downside.

How to conform to a self-made protocol?

I have a class with an delegate property. Anyone who wants to be a delegate must conform to a protocol. I defined everything like this:
#import <UIKit/UIKit.h>
#protocol TheDelegateProtocol;
#interface MyClass : UIView {
id<TheDelegateProtocol> theDelegate;
}
#property (nonatomic, assign) id<TheDelegateProtocol> theDelegate;
#end
#protocol TheDelegateProtocol<NSObject>
#required
- (void)fooBarWithFoo:(CGFloat)foo;
#end
Now the crazy thing is: I have another class that wants to be the delegate. So it conforms to that protocol, like this:
#import <Foundation/Foundation.h>
#class MyClass; // forward declaration. importet in implementation.
#protocol TheDelegateProtocol; // need forward declaration here, right?
#interface OtherClass : NSObject <TheDelegateProtocol> {
// ivars
}
#end
I can't get that to work. It says: "No definition of protocol 'TheDelegateProtocol' found". Well, that protocol is defined in MyClass, and I am importing MyClass in the implementation. Any idea what's wrong there?
Figured out something: In a method where I try to assign the protocol, it is telling me, that OtherClass does not conform to the protocol. But it does! That makes no sense. I also added the protocol method in the header....
Put the definition of the protocol in a separate file.
#import that file into any header file that needs it.
I think you need to #import the header file that defines the protocol. How can the compiler know which methods are available without it?
If you use another class (i.e., as an ivar or as a parameter to a method) then you can use a forward declaration. But if you subclass then you need to #import.
The compiler's warning is correct. OtherClass doesn't conform to the protocol because it doesn't declare the required fooBarWithFoo method that the protocol expects.
Have you tried it this way?
#import "MyClass.h"
#interface OtherClass : NSObject <TheDelegateProtocol> {
// ivars
}
- (void)fooBarWithFoo:(CGFloat)foo; // <<< missing bit
#end
He doesn't need to declare the methods to conform to the protocol. He only need to implement them in the .m file.
Is this a warning? because sometimes it does that when you have circular references and stuff, and it gets confused, but in reality its ok, have u tried running it to see if it works? In my project i have a bunch of warning about protocols not found, they are there though and it works fine... What you can do to get rid of the warning is try defining the protocol outside the class on some other .h file. You also dont really need the forward declaration, you can just do #import of the .h file its defined in
Your two classes differ in their use of the protocol.
MyClass does not implement the protocol, it has an attibute that is a pointer to a class that implements the protocol.
OtherClass should implement the protocol.
OtherClass needs to have available before its interface is defined all the details of the protocols, interfaces and classes that it inherits from. Thus you need the protocol in a header to be #imported in OtherClass.h
MyClass just needs to know the protocol exists in its interface.
Note on Stephen's reply subclassing is the case you can't use forward declarations of classes. (In the example OtherClass is a subclass of NSObject)
Also see Apple's Communicating with Objects, which discusses delegates, protocols, and selectors.