2010-11-16 3 views
0

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

#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 

ответ

0

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

[successViewController print];

1

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

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

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

0

Вы никогда не вызываете делегатов 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