Reputation: 343
I'm new to objective-c and it is still unclear to me of the following are possible
EDITS:
This is how I used and implemented my protocol:
@protocol myProtocol <NSObject>
@required
- (void)doneAction:(NSDate *)dateSelected;
@end
@interface datePickerView : UIView
@property (strong, nonatomic) UIDatePicker *datePicker;
@property (strong, nonatomic) UIButton *doneButton;
@property (strong, nonatomic) NSObject<myProtocol> *datePickerProtocol;
- (id)initWithDetails:(UIDatePicker *)datePick doneBtn:(UIButton *)doneBtn;
- (void)show;
@end
Here is the implementation of "datePickerView"
@synthesize datePicker = _datePicker;
@synthesize doneButton = _doneButton;
@synthesize datePickerProtocol = _datePickerProtocol;
- (id)initWithDetails:(UIDatePicker *)datePick doneBtn:(UIButton *)doneBtn
{
_datePicker = datePick;
_doneButton = doneBtn;
[_doneButton addTarget:self action:@selector(doneButtonClicked) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_datePicker];
[self addSubview:_doneButton];
}
- (void)doneButtonClicked
{
/** Code to hide the view goes here **/
if (_datePickerProtocol != nil)
[_datePickerProtocol doneAction:_datePicker.date];
}
Here is the class that is using the "datePickerView"
/** .h file **/
@interface myController : UITableViewController <myProtocol>
{
}
@property (strong, nonatomic) IBOutlet UIDatePicker *datePicker;
@property (strong, nonatomic) IBOutlet UIButton *datePickDone;
/** More definitions goes here **/
/** .m file **/
@synthesize datePicker = _datePicker;
@synthesize datePickDone = _datePickDone;
/** More code goes here **/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
if ((![selectedCell.reuseIdentifier isEqualToString:@"dateAppliedCellIdentifier"]) &&
(![selectedCell.reuseIdentifier isEqualToString:@"closingDateCellIdentifier"]))
return;
if (_datePicker.superview == nil)
{
datePickerView = [[datePickerView alloc] initWithDetails:_datePicker doneBtn:_datePickDone];
[self.view.window addSubview: datePickerView];
}
/**
THIS IS WHERE I WANT TO PASS AN INSTANCE OF THE PROTOCOL (BUT AS ADVISED,
IT IS NOT POSSIBLE) DEPENDING ON WHICH CELL WAS TAPPED. THE REASON I WANT
PASS AN INSTANCE OF THE PROTOCOL INSTEAD OF "SELF" IS BECAUSE I WANT
TO AVOID DOING MULTIPLE "IF" STATEMENTS INSIDE
"(void)doneAction:(NSDate *)dateSelected" METHOD. I WOULD LIKE TO DO THE IFs
HERE AND PASS THE CORRECT INSTANCE OF THE PROTOCOL DEPENDING ON WHICH CELL
WAS TAPPED. EACH INSTANCE OF THE PROTOCOLS HAVE DIFFERENT IMPLEMENTATIONS OF
"doneAction".
**/
[datePickerView setDatePickerProtocol:self];
[datePickerView show];
}
//implementation of the protocol method
- (void)doneAction:(NSDate *)dateSelected
{
//IF STATEMENTS GOES HERE DEPENDING ON WHICH CELL WAS TAPPED
NSLog(@"Done action is called!");
}
Please see my comments on the code, above this line [datePickerView setDatePickerProtocol:self]. Since I cannot instantiate protocols and assign to variables, is there an alternative or a better way of achieving my goal aside from implementing "myProtocol" from the controller and doing multiple IF statements inside "doneAction" method?
Based from the answers, it seems like I need to define classes that implements "myProtocol" and create instance of those classes and pass to "datePickerView setDatePickerProtocol". Is my understanding correct or is this reasonable to do?
Upvotes: 2
Views: 4414
Reputation: 124997
A protocol is just an interface -- there's no implementation. So even if you could instantiate a protocol (which you can't), you'd still need some way to supply the implementation of the protocol's interface.
The whole point of a protocol is that it lets you specify only the interface, and any class can implement that protocol. For example, the MapKit framework in iOS provides the MKAnnotation
protocol, which defines the interface to a map annotation object. You can implement MKAnnotation
in any class you like. If you adopt MKAnnotation
in some class of yours, you're essentially promising that that class provides certain methods, namely -coordinate
, -setCoordinate:
, -title
, and -subtitle
. The ability to do that is important in a single-inheritance language like Objective-C -- it means that you can make any class you like an annotation, you don't have to subclass some provided annotation class.
Your datePickerProtocol
property points to an object that implements myProtocol
, not an instance of myProtocol
itself (again, that wouldn't make sense). If that's really what you want, then you're doing it fine... you can declare a pointer to an object that implements someProtocol
as id<someProtocol>
or NSObject<someProtocol>*
.
Alternately, if you want to refer to the actual protocol itself rather than to an object that implements the protocol, you can do that. Objective-C provides the Protocol
type that's similar to the Class
type: just as any given class is an object of type Class
, any given protocol is an object of type Protocol
. You can use the @protocol
directive to get the Protocol object for a particular protocol. There's more information in the Objective-C Runtime Reference.
Upvotes: 2
Reputation: 6037
No protocols can not have instances created from them, if you could they would be just classes. Protocols are simply a way to define a set of methods that any class can implement, that way you do not have to use inheritance to have two different classes with the same methods. Subclassing a classes you are sharing bother the interface of the parent class and the implementation, it makes sense to sometime share the interface between classes without sharing any implementation.
Upvotes: 3