4

次のようなことが起こるまで、最終的にデリゲートの概念を理解できたと思いました。ヘッダーファイルを変更してデリゲートへの参照を削除しても、アラートは引き続き機能しました。唯一の違いは、コードヒントが失われることです。

//.h
#import <UIKit/UIKit.h>
//@interface ViewController : UIViewController <UIAlertViewDelegate> 
@interface ViewController : UIViewController 
- (IBAction)showMessage:(id)sender;
@end

//.m
#import "ViewController.h"
@implementation ViewController
- (IBAction)showMessage:(id)sender {
    UIAlertView *message = [[UIAlertView alloc] initWithTitle:@"Hello World!" 
                                                      message:@"Message." 
                                                     delegate:self 
                                            cancelButtonTitle:@"Cancel" 
                                            otherButtonTitles:@"Button 1", @"Button 2", nil];
    [message show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *title = [alertView buttonTitleAtIndex:buttonIndex];

    if([title isEqualToString:@"Button 1"])
    {
        NSLog(@"Button 1 was selected.");
    }   
}
@end
4

4 に答える 4

9

ヘッダー内の<UIAlertViewDelegate>は、クラスにデリゲートメソッドを実装する予定であることをコンパイラに示すだけです。@requiredとしてマークされたデリゲートメソッドを実装しない場合は警告が表示されますが、ほとんどのデリゲートメソッドは通常@optionalであるため、コードは正常にコンパイルおよび実行されます。ただし、ヘッダーにデリゲートを追加するべきではないという意味ではありません。

于 2012-05-17T16:49:46.090 に答える
6

あなたはすでに回答を受け入れていますが、この問題にはそこで取り上げられている以上のことがあります。

UIAlertViewDelegateデリゲート デザイン パターンを実装するプロトコルです。特定のプロトコルを採用することによって、(特に必要なメソッドがない場合) 準拠していることをランタイムに公式に通知する必要がある場合とない場合がありますが、これはプロトコルを宣言するクラスの設計に依存します。次のように、クラスを宣言するときに <> にプロトコル名を入れることで、クラスにプロトコルを採用します。

@interface MyClass : NSObject <delegateProtocolName>  

委譲される多くのプロトコル メソッドはオプション メソッドであるため、採用クラスが次のような特定のメソッドを実装しているかどうかをテストすることがよくあります。

if ([self.delegate respondsToSelector:@selector(delegatedMethod:)]) {
    // Do something
}

この場合、特定のデリゲート メソッドが実装されているかどうかを確認するためのテストであるため、ヘッダー ファイルのプロトコルに準拠する必要はありません。

ただし、テストは代わりに次のように記述できます (特に、同じ関数で複数の必要なメソッド/プロパティを参照する必要がある場合)。

if ([self.delegate conformsToProtocol:@protocol(delegateProtocolName)]) {
    // Do something
}

この場合、ヘッダー ファイルのプロトコルに準拠する必要があります。そうしないと、テストに合格しません。

ドキュメントを引用するにはconformsToProtocol( The Objective-C Programming Languageから取得し、私が強調を追加しました):

このメソッドは、上記のように、ヘッダー ファイル内の正式な宣言のみに基づいて適合性を判断します。プロトコルで宣言されたメソッドが実際に実装されているかどうかはチェックしません。それはプログラマーの責任です。

于 2012-05-17T17:33:54.427 に答える
3

答えは、Apple はクラスに UIAlertViewDelegate プロトコルを実装することを要求したくないということです。Apple がそれを要求したい場合は、UIAlertView のデリゲート プロパティを type にしid<UIAlertViewDelegate>ます。ドキュメントを見ると、そうではありません。

UIAlertView クラス リファレンス

@property(nonatomic, assign) id delegate

彼らには、それを達成できなかった理由があるに違いありません@property(nonatomic, assign) id<UIAlertViewDelegate> delegate

于 2012-05-17T17:03:11.823 に答える
1

クラスで言及した <UIAlertViewDelegate> は、このクラスに AlertView デリゲートのメソッドを実装していることを意味しますつまり、ViewControllerdelegate:selfは、このオブジェクトのデリゲート メソッドが現在のクラスで定義されていることを意味します。

他のクラスで AlertView デリゲートのメソッドを定義する場合は、そのクラスで <UIAlertViewDelegate> を指定し、その特定のクラスでメソッドを実装する必要があります。

また、delegate:(classname) を変更する必要があります。

于 2012-05-18T06:57:01.523 に答える