Как делегат работает в objective-C?

  • Кто-нибудь знает, где я могу найти хорошее объяснение/учебник о том, что и как делегат приложения работает в objective-C?
  • Две книги, которые у меня есть, не опираются на delegates и не очень хорошо объясняют им, чтобы я действительно понимал их силу и функции.

Ответ 1

В случае сомнений проверьте docs!

В принципе, делегирование - это способ позволить объектам взаимодействовать друг с другом без создания сильных взаимозависимостей между ними, поскольку это делает дизайн вашего приложения менее гибким. Вместо объектов, управляющих друг другом, у них может быть делегат, которому они отправляют (или делегируют) сообщения, и делегат делает все, что они делают, чтобы реагировать на это сообщение и действовать, а затем обычно возвращать что-то обратно на другой объект.

Делегирование также является лучшей альтернативой подклассу. Вместо того, чтобы создавать собственные пользовательские классы, чтобы немного изменить способ поведения других объектов или передавать их данные, делегирование позволяет объектам отправлять сообщения своим делегатам для работы над ними без накладных расходов на создание подклассов для внесения незначительных изменений в другие объекты.

Конечно, основным недостатком делегирования является то, что доступные методы делегатов зависят от того, что инженеры Apple предвидят как полезные и какие общие реализации они ожидают от людей, что накладывает ограничение на то, что вы можете достичь. Хотя, как указал Куинн Тейлор, это специфично для фреймворков Cocoa и поэтому не применяется во всех ситуациях.

Если делегирование является опцией по подклассу, тогда возьмите его, потому что это гораздо более чистый способ управления вашим кодом и взаимодействиями между объектами.

Ответ 2

Как описано выше, делегат не является функцией iOS или Objective-C, а просто является техникой программирования и не требует никакой конкретной поддержки языка.

Класс (e, g, classA) может быть записан таким образом, что его методы getData и doSomething могут быть реализованы не самим собой, а делегатом (возможно, потому, что classA не знает, какие данные будут или что это будет нужно сделать).

Чтобы достичь этого, classA предоставляет свойство, обычно называемое делегатом (это всего лишь указатель на класс - делегат, - который реализует делегированные методы), а затем, когда он хочет вызывать эти методы, он фактически вызывает методов в делегате:

[self.delegate getData];

и

[self.delegate doSomething];

self.delegate может быть первоначально установлен на self:

self.delegate = self;

то есть. classA реализует собственную версию этих методов, если они не делегированы.

Любой другой класс, желающий быть разработчиком методов (т.е. быть делегатом и, возможно, переопределять реализацию по умолчанию класса), должен сначала установить делегат класса A сам. поэтому, если classB хотел быть делегатом для этих методов, в классе B мы имели бы:

classA.delegate = self;

Поэтому, когда classA вызывает эти делегированные методы, он фактически вызывает классB для реализации этих методов, ничего не зная о классе B или даже о том, что он существует, а classB не имеет подкласса classA.

Ограничение заключается в том, что classB может только переопределять методы, которые classA хочет делегировать - с помощью подкласса вы можете переопределить любой метод.

Протоколы используются для формализации процесса делегирования путем определения списка методов, которые делегат может реализовать должен (делегат не предоставляет версию метода по умолчанию и метод должен быть реализован где-то) или может быть опционально реализован делегатом (т.е. у делегирования есть его собственная версия или нет никакого значения, если метод не реализован).

Ответ 3

Делегаты - это шаблон проектирования; нет специального синтаксиса или поддержки языка.

Делегат - это просто объект, которому другой объект отправляет сообщения, когда происходят определенные вещи, так что делегат может обрабатывать специфические для приложения детали, для которых не был создан исходный объект. Это способ настройки поведения без подкласса.

Ответ 4

Я пытаюсь его проработать с помощью простой программы

Два класса

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

Teacher.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;
}

ОБЪЯСНЕНИЕ:

  • Из основного метода, когда initWithStudent: студент выполнит

    1.1 Свойству объекта учителя 'student' будет присвоен объект-ученик.

    1.2 self.student.delegate = self      означает, что делегат объекта объекта указывает на объект учителя

  • Из основного метода, когда [student studentInfo] будет называться

    2.1 [self.delegate replyToSelector: @selector (имя учителя)] Здесь делегат уже         указывает на объект учителя, поэтому он может вызывать метод экземпляра "teacherName".

    2.2, поэтому [self.delegate performSelector: @selector (имя учителя)]          будет выполняться легко.

Похоже, объект Teacher назначает делегат объекту-ученику для вызова его собственного метода.

Это относительная идея, когда мы видим, что объект-ученик называется методом "teacherName", но в основном он выполняется самим объектом-учителем.

Ответ 5

Только представьте, что вы звоните по телефону и заказываете пиццу. Затем к вашему дому приходит мальчик доставки пиццы (это делегат), и когда вы платите за пиццу, мальчик-пицца доставки возвращает деньги в свой ресторан.

you = объект доставки boy = делегат ресторан = объект