69

Objective C の iPhone 開発における「デリゲート」とは何ですか?

4

10 に答える 10

80

デリゲートは、デリゲート所有者が呼び出す方法を知っている一連のメソッドを持つオブジェクトへのポインターです。つまり、後で作成されたオブジェクトから特定のコールバックを有効にするメカニズムです。

良い例UIAlertViewです。UIAlertViewユーザーに短いメッセージ ボックスを表示するオブジェクトを作成し、 "OK" と "キャンセル" のような 2 つのボタンを選択できるようにします。にはUIAlertViewコールバックする方法が必要ですが、コールバックするオブジェクトとコールするメソッドに関する情報がありません。

この問題を解決するには、selfポインターをUIAlertViewデリゲート オブジェクトとして に送信し、その代わりに (UIAlertViewDelegateオブジェクトのヘッダー ファイルで を宣言することによって) をUIAlertView呼び出すことができるいくつかのメソッド ( など) を実装することに同意しますalertView:clickedButtonAtIndex:

デリゲート デザイン パターンとその他のコールバック手法の概要については、この投稿をご覧ください。

参考文献:

于 2010-03-28T21:12:59.107 に答える
56

この議論を見る

デリゲートを使用すると、イベントが発生したときに、あるオブジェクトから別のオブジェクトにメッセージを送信できます。たとえば、NSURLConnection クラスを使用して Web サイトから非同期にデータをダウンロードしている場合。NSURLConnection には、次の 3 つの一般的なデリゲートがあります。

 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

NSURLConnection でエラーが発生したとき、正常に終了したとき、または Web サイトから応答を受信したときに、これらのデリゲートの 1 つ以上が呼び出されます。

于 2010-03-28T19:03:46.493 に答える
21

デリゲートは設計パターンです。特別な構文や言語サポートはありません。

デリゲートは、特定のことが発生したときに別のオブジェクトがメッセージを送信する単なるオブジェクトであるため、デリゲートは、元のオブジェクトが設計されていないアプリ固有の詳細を処理できます。これは、サブクラス化せずに動作をカスタマイズする方法です。

于 2010-03-28T18:56:06.103 に答える
5

このウィキペディアの記事が最もよく説明していると思います: http://en.wikipedia.org/wiki/Delegation_pattern

これは、設計パターンの「単なる」実装であり、Objective-C では非常に一般的です。

于 2010-03-28T18:57:24.280 に答える
3

お願いします!デリゲートがiOSでどのように機能するかを理解するには、以下の簡単なステップバイステップのチュートリアルを確認してください。

iOSで委任する

2つのViewControllerを作成しました(一方から他方にデータを送信するため)

  1. FirstViewControllerはデリゲート(データを提供する)を実装します。
  2. SecondViewControllerはデリゲート(データを受信します)を宣言します。

これがあなたを助けるかもしれないサンプルコードです。

AppDelegate.h


#import <UIKit/UIKit.h>

@class FirstViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) FirstViewController *firstViewController;

@end

AppDelegate.m


#import "AppDelegate.h"
#import "FirstViewController.h"

@implementation AppDelegate

@synthesize firstViewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    //create instance of FirstViewController
    firstViewController = [[FirstViewController alloc] init];

    //create UINavigationController instance using firstViewController
    UINavigationController *firstView = [[UINavigationController alloc] initWithRootViewController:firstViewController];

    //added navigation controller to window as a rootViewController
    self.window.rootViewController = firstView;

    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

FirstViewController.h


#import <UIKit/UIKit.h>
#import "SecondViewController.h"

@interface FirstViewController : UIViewController<MyDelegate>

@property (nonatomic, retain) NSString *mesasgeData;

@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *nextButton;

- (IBAction)buttonPressed:(id)sender;

@property (nonatomic, strong) SecondViewController *secondViewController;

@end

FirstViewController.m


#import "FirstViewController.h"

@interface FirstViewController ()
@end

@implementation FirstViewController

@synthesize mesasgeData;
@synthesize textField;
@synthesize secondViewController;

#pragma mark - View Controller's Life Cycle methods

- (void)viewDidLoad
{
    [super viewDidLoad];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];

}

#pragma mark - Button Click event handling method

- (IBAction)buttonPressed:(id)sender {

    //get the input data from text feild and store into string
    mesasgeData = textField.text;

    //go keypad back when button clicked from textfield
    [textField resignFirstResponder];

    //crating instance of second view controller
    secondViewController = [[SecondViewController alloc]init];

    //it says SecondViewController is implementing MyDelegate
    secondViewController.myDelegate = self;

    //loading new view via navigation controller
    [self.navigationController pushViewController:secondViewController animated:YES];    
}

#pragma mark - MyDelegate's method implementation

-(NSString *) getMessageString{
    return mesasgeData;
}

@end

SecondViewController.h


//declare our own delegate
@protocol MyDelegate <NSObject>

-(NSString *) getMessageString;

@end

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *messageLabel;

@property (nonatomic, retain) id <MyDelegate> myDelegate;

@end

SecondViewController.m


#import "SecondViewController.h"

@interface SecondViewController ()
@end

@implementation SecondViewController

@synthesize messageLabel;
@synthesize myDelegate;

- (void)viewDidLoad
{
    [super viewDidLoad];    
    messageLabel.text = [myDelegate getMessageString];    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end
于 2013-02-27T12:27:36.730 に答える
3

デリゲートを理解すれば、これらすべての答えは非常に理にかなっていると思います。個人的には、私は C/C++ の土地から来て、その前は Fortran などの手続き型言語だったので、C++ パラダイムで同様の類似物を見つけるための私の 2 分間の取り組みを次に示します。

C++/Java プログラマーにデリゲートについて説明する場合、私はこう言います。

デリゲートとは これらは、別のクラス内のクラスへの静的ポインターです。ポインターを割り当てたら、そのクラスの関数/メソッドを呼び出すことができます。したがって、クラスの一部の関数は別のクラスに「委譲」されます (C++ の世界では、クラス オブジェクト ポインターによるポインター)。

プロトコルとは?概念的には、デリゲート クラスとして割り当てるクラスのヘッダー ファイルと同様の目的を果たします。プロトコルは、ポインタがクラス内でデリゲートとして設定されたクラスに実装する必要があるメソッドを定義する明示的な方法です。

C++で同様のことを行うにはどうすればよいですか? C++ でこれを行おうとすると、クラス定義でクラス (オブジェクト) へのポインターを定義し、それらを他のクラスに接続して、基本クラスへのデリゲートとして追加の関数を提供します。しかし、この配線はコード内で維持する必要があり、扱いにくく、エラーが発生しやすくなります。Objective C は、プログラマーがこの規定を維持するのが得意ではないことを前提としており、クリーンな実装を強制するためにコンパイラーの制限を提供しています。

于 2013-06-20T13:31:15.600 に答える
3

簡単なプログラムで詳しく説明してみます

2つのクラス

Student.h

#import <Foundation/Foundation.h>

@interface Student : NSObject
@property (weak) id  delegate;
- (void) studentInfo;
@end

Student.m

#import "Student.h"
@implementation Student
- (void) studentInfo
{
    NSString *teacherName;
    if ([self.delegate respondsToSelector:@selector(teacherName)]) {
        teacherName = [self.delegate performSelector:@selector(teacherName)];
    }
    NSLog(@"\n Student name is XYZ\n Teacher name is %@",teacherName);
}
@end

先生.h

#import <Foundation/Foundation.h>
#import "Student.h>

@interface Teacher: NSObject
@property (strong,nonatomic) Student *student;
- (NSString *) teacherName;
- (id) initWithStudent:(Student *)student;
@end

Teacher.m

#import "Teacher.h"

@implementation Teacher

- (NSString *) teacherName
{
    return @"ABC";
}
- (id) initWithStudent:(Student *)student
{
    self = [ super init];
    if (self) {
        self.student = student;
        self.student.delegate = self;
    }
    return self;
}
@end

main.m

#import <Foundation/Foundation.h>
#import "Teacher.h"
int main ( int argc, const char* argv[])
{
    @autoreleasepool {

        Student *student = [[Student alloc] init];
        Teacher *teacher = [[Teacher alloc] initWithStudent:student];

        [student studentInfo];

    }
    return 0;
}

説明:::

  1. メインメソッドからいつinitWithStudent:student実行するか

    1.1 Teacher のオブジェクトのプロパティ ' student ' には、 Student オブジェクトが割り当てられます。

    1.2 self.student.delegate = self

        means student object's delegate will points to teacher object
    
  2. メインメソッドからいつ[student studentInfo]呼び出されるか

    2.1 [self.delegate respondToSelector:@selector(teacherName)] ここで、デリゲートはすでに教師オブジェクトを指しているため、'teacherName' インスタンス メソッドを呼び出すことができます。

    2.2なので[self.delegate performSelector:@selector(teacherName)] 簡単に実行できます。

Teacher オブジェクトがデリゲートを Student オブジェクトに割り当てて、独自のメソッドを呼び出すように見えます。

これは相対的な考え方であり、学生オブジェクトが「teacherName」メソッドと呼ばれていることがわかりますが、基本的には教師オブジェクト自体によって行われます。

于 2013-08-09T06:29:35.003 に答える
1

デリゲートは、ユーザーのテーピング アクションをキャプチャし、ユーザーのテーピング アクションに従って特定のアクションを実行します。

于 2012-07-18T09:19:14.290 に答える
1

デリゲートは Objects C の自動イベントを発生させます。デリゲートを Object に設定すると、デリゲート メソッドを介して別のオブジェクトにメッセージが送信されます。

これは、サブクラス化を必要とせずにクラスの動作を変更する方法です。

デリゲート メソッドを持つ各オブジェクト。特定のオブジェクトがユーザー インタラクションとプログラム フロー サイクルに参加すると、これらのデリゲート メソッドが起動します。

簡単に言うと、委譲とは、オブジェクト間に強い相互依存関係を作成することなく、オブジェクトが相互に対話できるようにする方法です。

于 2012-03-01T13:17:55.107 に答える
0

デリゲートは、そのオブジェクトに代わってメソッドを呼び出すことができるオブジェクトのインスタンスに他なりません。また、そのオブジェクトのrumtimeでメソッドを作成するのに役立ちます。

于 2012-11-24T13:05:40.970 に答える