Вопрос об объективном протоколе C - PullRequest
0 голосов
/ 16 ноября 2010

Я пытаюсь выучить протокол цели С.
Я пишу два файла, первый - FirstViewController.h, в котором есть протокол «печать».Я объявляю класс FirstViewController в successViewController с методом делегата «print».Вопрос в том, почему вывод на консоль "C".Почему я не могу получить вывод "B"?Почему метод протокола не выполняется?

#import <UIKit/UIKit.h>
#import "FirstViewController.h"
@interface successViewController : UIViewController <FirstViewControllerDelegate> {
}
@end

#import "successViewController.h"
#import "FirstViewController.h"
@implementation successViewController
- (void)viewDidLoad {
FirstViewController *firstViewController= [[FirstViewController alloc] init];
firstViewController.delegate=self;
NSLog(@"C");
 [super viewDidLoad];
}
 -(void) print{
 NSLog(@"B");
 }
@end

#import <Foundation/Foundation.h>
@class FirstViewController;
@protocol FirstViewControllerDelegate <NSObject>
- (void) print;
@end
@interface FirstViewController : NSObject {
id <FirstViewControllerDelegate> delegate;

}
@property (nonatomic, assign) id <FirstViewControllerDelegate> delegate;
@end

#import "FirstViewController.h"
@implementation FirstViewController
@synthesize delegate;
@end

Ответы [ 3 ]

1 голос
/ 16 ноября 2010

Потому что вы никогда не вызываете метод print. Где вы ожидали, что это будет называться?

Протоколы Objective-C позволяют вам указать, что класс способен выполнять определенные действия. В вашем примере successViewController объявлен FirstViewControllerDelegate, что означает, что он способен выполнять обязанности, требуемые FirstViewController его делегата. Это скорее контракт на программирование между классами, который может быть проверен компилятором.

В качестве примечания: классы в Objective-C всегда должны начинаться с заглавной буквы, а методы всегда должны начинаться со строчной буквы. Ваш FirstViewController следует этому правилу, а successViewController - нет.

0 голосов
/ 16 ноября 2010

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

Предположим, у нас есть класс с именем Delay, единственное, что он делает, - это подождет, когда будет вызван start, и затем скажетэто делегат, что он ждал.При желании делегат может Delay сообщить, сколько ждать, если клиенту все равно, предполагается задержка в 1 секунду.

Некоторые правила:

  1. Первый аргумент из всехМетоды делегата должны быть самим отправителем, никогда не иметь методов делегата без аргументов.
  2. Имя метода делегата должно включать одно из слов:
    1. will - если метод вызывается до того, как произойдет что-то неизбежное,Пример applicationWillTerminate:
    2. did - если метод вызывается после того, как что-то произошло.Пример scrollViewDidScroll:
    3. should - если метод возвращает BOOL для сигнала, если что-то должно произойти.Пример textFieldShouldClear:
  3. Назовите метод, чтобы сказать, что произошло, а не то, что вы ожидаете от делегата.
    1. Единственное исключение - если клиент должен что-то вернуть, тогда это что-то должно быть частью имени.Пример: tableView:editingStyleForRowAtIndexPath:

Вот простое определение и реализация.Обратите внимание, что я даже не проверяю, был ли установлен делегат, поскольку вызов методов на nil в любом случае просто игнорируется.

// Delay.h
@protocol DelayDelegate;

@interface Delay : NSObject {
@private
  id<DelayDelegate> _delegate;
}
@property(nonatomic, assign) id<DelayDelegate> delegate;
-(void)start;
@end

@protocol DelayDelegate <NSObject>
@required
-(void)delayDidComplete:(Delay*)delay;
@optional
-(NSTimeInterval)timeIntervalForDelay:(Delay*)delay;
@end


// Delay.m
@interface Delay
@synthesize = delegate = _delegate;

-(void)start {
   NSTimeInterval delay = 1.0;
   if ([self.delegate respondsToSelector:@selector(timeIntervalForDelay:)]) {
     delay = [self.delegate timeIntervalForDelay:self];
   }
   [self performSelector:@selector(fireDelay) withObject:nil afterDelay:delay];
}

-(void)fireDelay {
  [self.delegate delayDidComplete:self];
}
@end
0 голосов
/ 16 ноября 2010

Вам нужно вызвать метод, который вы хотите использовать.

[successViewController print];

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