2

私はObjective-cを初めて使用しますが、次のことが可能かどうかはまだわかりません。

  1. プロトコルをインスタンス化することは可能ですか?
  2. プロトコルをインスタンス化できる場合、必要なメソッドを実装するにはどうすればよいですか?

編集:

これは私が私のプロトコルを使用して実装した方法です:

@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

これが「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];
}

これが「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!");
}

この行[datePickerViewsetDatePickerProtocol:self]の上にあるコードに関する私のコメントを参照してください。プロトコルをインスタンス化して変数に割り当てることができないので、コントローラーから「myProtocol」を実装し、「doneAction」メソッド内で複数のIFステートメントを実行する以外に、目標を達成するための代替またはより良い方法はありますか?

回答から、「myProtocol」を実装するクラスを定義し、それらのクラスのインスタンスを作成して「datePickerViewsetDatePickerProtocol」に渡す必要があるようです。私の理解は正しいですか、それともこれは合理的ですか?

4

2 に答える 2

3

プロトコルは、それらから作成されたインスタンスを持つことはできません。できれば、それらは単なるクラスです。プロトコルは、任意のクラスが実装できる一連のメソッドを定義する方法にすぎません。そのため、同じメソッドを持つ 2 つの異なるクラスを持つために継承を使用する必要はありません。共有しているクラスをサブクラス化すると、親クラスのインターフェイスと実装が煩わされます。実装を共有せずに、クラス間でインターフェイスを共有することは理にかなっています。

于 2012-10-21T23:23:56.227 に答える
2

プロトコルは単なるインターフェースであり、実装はありません。したがって、プロトコルをインスタンス化できたとしても(それはできません)、プロトコルのインターフェイスの実装を提供するための何らかの方法が必要になります。

プロトコルの要点は、インターフェイスのみを指定できることであり、どのクラスでもそのプロトコルを実装できます。たとえば、iOSのMapKitフレームワークはMKAnnotation、マップ注釈オブジェクトへのインターフェイスを定義するプロトコルを提供します。MKAnnotation好きなクラスに実装できます。あるクラスで採用する場合MKAnnotation、そのクラスが特定のメソッド、つまり、、、、およびを提供することを本質的に約束して-coordinateいます。これを行う機能は、Objective-Cのような単一継承言語では重要です。つまり、アノテーションが好きなクラスを作成でき提供されているアノテーションクラスをサブクラス化する必要はありません。-setCoordinate:-title-subtitle

プロパティは、それ自体のインスタンスではなく、datePickerProtocol実装するオブジェクトを指します(これも意味がありません)。それが本当にあなたが望むものであるなら、あなたはそれをうまくやっています...あなたはまたはとして実装するオブジェクトへのポインタを宣言することができます。myProtocolmyProtocolsomeProtocolid<someProtocol>NSObject<someProtocol>*

または、プロトコルを実装するオブジェクトではなく、実際のプロトコル自体を参照する場合は、それを行うことができます。Objective-Cは、Protocolタイプに類似したタイプを提供しClassます。特定のクラスがタイプのオブジェクトであるのと同様に、Class特定のプロトコルはタイプのオブジェクトですProtocol。ディレクティブを使用し@protocolて、特定のプロトコルのプロトコルオブジェクトを取得できます。詳細については、Objective-Cランタイムリファレンスを参照してください。

于 2012-10-21T23:41:39.413 に答える