简体   繁体   中英

objective-c protocol as variable (instance)

I'm new to objective-c and it is still unclear to me of the following are possible

  1. Is it possible to instantiate a protocol?
  2. If it is possible to instantiate a protocol, how do I implement the required methods?

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?

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM