I have a UIView subclass called NumberPickerView. I'm writing a delegate method for it. The compiler won't let me pass an instance of NumberPickerView as an parameter in that method. What am I missing?
#protocol NumberPickerViewDelegate
-(void) numberPickerDidChangeSelection:(NumberPickerView *)numberPickerView;
//error: expected a type
#end
#interface NumberPickerView : UIView <UIScrollViewDelegate> {
id <NumberPickerViewDelegate> delegate;
}
Actually it CAN. At that point compiler doesn't know about NumberPickerView class
#class NumberPickerView;
add it over protocol declaration to let compiler know about that class... It's called forward declaration.
For better understanding check this out:
iPhone+Difference Between writing #classname & #import"classname.h" in Xcode
OR
move protocol declaration below the class NumberPickerView definition but in that case you should also add at top:
#protocol NumberPickerViewDelegate;
Not to get warnings using id<NumberPickerViewDelegate>delegate
You can change parameter type to id instead of NumberPickerView * and pass any class object afterword as bellow
#protocol NumberPickerViewDelegate
-(void) numberPickerDidChangeSelection:(id)numberPickerView;
#end
#interface NumberPickerView : UIView <UIScrollViewDelegate> {
id <NumberPickerViewDelegate> delegate;
}
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.
I just got started working with delegates.
from some reason I cannot do it, and I see errors.
I tried to do the next code on a new project and it was OK, but when i'm moving this code to my main project I have a few issues.
my NSObject class .h:
#protocol myNSObjectClassDelegate <NSObject>
#required
-(void)doSomething;
#end
#interface GeneralMethods : NSObject
#property (nonatomic,strong) id<myNSObjectClassDelegate> delegate;
#end
my NSObject class .m:
#synthesize delegate;
-(void)SomeMethod {
if ([delegate respondsToSelector:#selector(doSomething)]) {
[delegate doSomething];
}
}
my UIViewController .h
#import "GeneralMethods.h"
#interface view : UIViewController<UIGestureRecognizerDelegate,
UINavigationControllerDelegate,
 UIImagePickerControllerDelegate,
myNSObjectClassDelegate>
The error is here at .h - Cannot find protocol declaration for 'myNSObjectClassDelegate'
my UIViewController .m
-(void)doSomething{
}
What am I doing wrong?
EDIT : I figure it out:
For some reason, at my NSObject class, if I'm moving the #import myUIViewcontroller after this:
#protocol myNSObjectClassDelegate <NSObject>
#required
-(void)doSomething;
#end
the problem solved.
We can't see all the code but after reading some more of the exchanges it looks like dependencies are maybe added out of order. I recommend moving the protocol into its own file and #import'ing it to all the places that use it. This way you definitely will be importing things in the order you expect.
In addition to that, the following property declaration:
#property (nonatomic,strong) id<myNSObjectClassDelegate> delegate;
Delegates should be declared as weak, not strong.
#property (nonatomic,weak) id<myNSObjectClassDelegate> delegate;
The reason is to avoid retain cycles/memory leaks. Typically, though not always the relationship looks like this:
Parent Object (usually Controller) -----STRONG-----> Child (View often)
View Thing ----WEAK--------> delegate (actually the Parent Object)
Now if the relationship is STRONG both ways, releasing the parent from all who own it will not be sufficient to release it since its child also holds an owning relationship to it.
Also you can omit the:
#synthesize delegate;
Auto property synthesis renders this obsolete.
Make sure to import your NSObject class .h. file into your UIViewController's .h file (or wherever you declare the protocol). As it stands, you haven't imported the header that declares the protocol so your view controller has no way of knowing that it exists.
Ex:
#import "FileWithProtocol.h"
#interface MyClass <MyProtocol>
...
#end
In the view controller .h file, try adding this line:
#protocol MyNSObjectClassDelegate;
before
#interface ...
I have a subclass defined like this
#protocol UMTextViewDelegate;
#interface UMTexView : UITextView <UITextViewDelegate> {
}
#property (nonatomic, assign) id<UMTextViewDelegate> delegate;
#end
#protocol UMTextViewDelegate <NSObject>
#optional
- (void)textViewDidSelectWordToDefine:(UMTexView*)textView;
#end
But I get a warning Property type 'id<UMTextViewDelegate>' is incompatible with type 'id<UITextViewDelegate>' inherited from 'UITextView'.
How do I suppress this warning ? I tried adding this :
#protocol UMTextViewDelegate <NSObject, UITextViewDelegate>
but no luck. !!
EDIT:
I am not using ARC
The problem you are having is about forward declarations. In the place where you are declaring the delegate, the compiler doesn't know that UMTextViewDelegate descends from UITextViewDelegate. The only thing it knows is that UMTextViewDelegate is a protocol.
You have to create a forward declaration for the class #class UMTexView;, then put the protocol declaration and then the class declaration.
On a separate note, it's obvious UMTexView is supposed to be the text delegate for itself. Maybe it would be easier to have UMTexView descending directly from UIView and put an UITextView inside it. Then you wouldn't have any problem with delegate collisions and the UITextViewDelegate would be unaccessible externally.
Using #Sulthan's answer, this is what I came up with and it squished the warning.
#class UMTextView;
#protocol UMTextViewDelegate <NSObject, UITextViewDelegate>
#optional
- (void)textViewDidSelectWordToDefine:(UMTextView*)textView;
#end
#interface UMTextView : UITextView <UITextViewDelegate>
#property (nonatomic, assign) id<UMTextViewDelegate> delegate;
#end
The forward declaration of UMTextView followed by protocol declaration tells UMTextView that UMTextViewDelegate is indeed descends from UITextViewDelegate. That way I don't have to the route of adding a uiview and then adding a uitextview inside that view.
I'm trying to make a category adopt a protocol, and I'm having a problem with what seems like a simple thing.
The interface declaration is:
#interface UIView (UIViewCategory) <DesiredProtocol>
And I was assuming the implementation declaration should be the same:
#implementation UIView (UIViewCategory) <DesiredProtocol>
But this gets a yellow warning in XCode, with the message: "Protocol qualifiers without 'id' is archaic".
So should the declaration be:
#implementation UIView (UIViewCategory) id<DesiredProtocol>
??
I can't find reference for this specific issue. Much thanks for all replies.
You don't need the protocol list on an #implementation block, whether it's a category or not.
#implementation UIView (UIViewCategory)
...
#end
This is how you declare a protocol
#protocol ProtocolName <NSObject>
//protocol methods
#end
Later it's property
#interface ProtocolClass: NSObject
{...}
#end
#property (nonatomic, unsafe_unretained) id <ProtocolName> delegate;
//Synthesize it!
And then you adopt it
#interface ClassThatAdoptsProtocol: NSObject <ProtocolName>{...}
I have started new iOS project and have added only one property in ViewControler header file. but it gives me error:
expected specifier-qualifier-list before 'property'
here is the code:
#import <UIKit/UIKit.h>
#interface QuoteGenViewController : UIViewController {
#property (retain) NSArray *myQuotes;
}
#end
Here the general structure of a class interface
#interface Class : Superclass
{
// Instance variable declarations.
// Theirs definition could be omitted since you can declare them
// in the implementation block or synthesize them using declared properties.
}
// Method and property declarations.
#end
Since a property provides a simple way to declare and implement an object’s accessor methods (getter/setter), you need to put them in the Method and property declarations section.
I really suggest to read ocDefiningClasses doc for this.
Hope that helps.
Your code should look like this:
#import <UIKit/UIKit.h>
#interface QuoteGenViewController : UIViewController {
}
#property (retain) NSArray *myQuotes;
#end