2014-12-29 2 views
-2

Может ли кто-нибудь объяснить основы того, как можно поместить свойство в протокол, чтобы получить доступ к его значению для разных контроллеров представлений?Попытка поместить свойство в протокол

В частности,, я пытаюсь поместить свойство MKMapView в протокол. У меня есть два контроллера Вид:

  1. Карта View Controller (Внутри него 2. Таблица List View Controller)
  2. Таблица Список View Controller

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

Карта View Controller .h

@protocol MapViewDelegate <MKMapViewDelegate> 

@property (nonatomic, strong) IBOutlet MKMapView *mapView; 

@end 

@interface PAWWallViewController : UIViewController <MapViewDelegate, ...> 

... 

@end 

Карта View Controller .h

... 
@synthesize mapView = _mapView 
... 

Table View Controller .h

@interface PAWWallPostsTableViewController : PFQueryTableViewController <MapViewDelegate...> 

... 

Настольный контроллер. м

... 
@synthesize mapView; 
... 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    // call super because we're a custom subclass. 
    [super tableView:tableView didSelectRowAtIndexPath:indexPath]; 

    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    PFObject *object = [self.objects objectAtIndex:indexPath.row]; 
    PAWPost *post = [[PAWPost alloc] initWithPFObject:object]; 

    [mapView setCenterCoordinate: post.coordinate animated:YES]; 

    [mapView selectAnnotation:post animated:YES]; 

    NSLog(@"MAP VIEW: %@", mapView); // STILL NULL 
} 
+0

Пожалуйста, укажите полный текст ошибки, которую вы видите. – bdesham

+0

Протокол не делает свойство магически доступным, он просто упрощает ссылку, не используя другой include. Чтобы ссылаться на свойство, вам нужен указатель на объект, содержащий свойство. –

+0

Я обновил его. После синтеза в обоих .m-файлах он теперь не отправляет ошибку. Но self.mapView возвращает null в журнале. Я добавил синтез, потому что я предупреждал, что синтез автоматического свойства не будет синтезировать свойство mapView. Прежде чем я добавил это, он отправил сообщение об ошибке: *** Завершение приложения из-за неотображенного исключения «NSUnknownKeyException», причина: «[ setValue: forUndefinedKey:]: этот класс не является ключевым значением, совместимым с кодировкой для ключевого mapView. ' *** – teenyton

ответ

0

Вот фон на свойства: Encapsulating Data.

Короче говоря, свойства - это быстрый способ определения метода геттера, метода сеттера и переменной экземпляра (также называемой ivar).

Если вы думаете об этом, то свойства, не связанные с автосинхронизацией в протоколах, являются правильным поведением, это немного удивительно. Протоколы определяют интерфейс, но никогда не создают код.

В вашем примере протокол:

@protocol MapViewDelegate <MKMapViewDelegate> 
@property (nonatomic, strong) IBOutlet MKMapView *mapView; 
@end 

создает интерфейс для -mapView и -setMapView:, но не создает реализацию этих методов.

Существует несколько способов получить необходимые методы в @implementation.

  1. Declare @synthesize mapView; в @implementation любого класса, который реализует MapViewDelegate. Вы уже обнаружили это. BTW: Я бы порекомендовал @synthesize mapView = _mapView;, потому что это то, как авто синтезирует имена ivar.
  2. Объявить @property (nonatomic, strong) IBOutlet MKMapView *mapView; в категории @interface любого класса, который содержит MapViewDelegate.
  3. Создайте методы экземпляра - (MKMapView *)mapView и - (void)setMapView:(MKMapView *)mapView.Это старый ручной маршрут для создания свойств. Помимо определения геттера и сеттера, вам нужно создать ivar для хранения значения. Примечание: я включил это только для полноты, это не рекомендация.
+0

Спасибо! Я применил первый способ, используя @synthesize mapView = _mapView; в моем контроллере просмотра стены. Теперь я получаю значение, но мне все же нужно работать над тем, чтобы получить это значение в контроллере табличного представления, который все еще возвращает null. – teenyton

+0

@teenyton - «но мне все еще нужно работать над тем, чтобы получить это значение для контроллера табличного представления, который все еще возвращает null» - помещение свойства в протокол не передает его, он просто говорит, что любой класс, реализующий протокол, должен предоставлять такие недвижимость. Свойства в ваших двух классах независимы, установка одной не повлияет на другую. – CRD

Смежные вопросы