【问题标题】:Trying to put property in protocol试图将属性放入协议中
【发布时间】:2014-12-29 03:19:31
【问题描述】:

有人能解释一下如何将属性放入协议中以便跨不同视图控制器访问它的值的基础知识吗?

具体来说,我正在尝试将 MKMapView 属性放入协议中。我有两个视图控制器:

  1. Map View Controller(里面是2.Table List View Controller)
  2. 表格列表视图控制器

为了能够在表列表视图控制器中选择与地图视图控制器中的注释相对应的帖子,我需要能够访问地图视图控制器中的地图视图。这就是我认为协议会派上用场的地方。

地图视图控制器.h

@protocol MapViewDelegate <MKMapViewDelegate>

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

@end

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

...

@end

地图视图控制器.h

...
@synthesize mapView = _mapView
...

表格视图控制器.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
}

【问题讨论】:

  • 请附上您看到的错误的全文。
  • 协议不会神奇地使属性可用,它只是让引用更容易,而无需使用其他包含。要引用一个属性,您需要一个指向包含该属性的对象的指针。
  • 我更新了。在两个 .m 文件中合成后,它现在不会发送错误。但是 self.mapView 在日志中返回 null。我添加了合成,因为我有警告说自动属性合成不会合成属性 mapView。在我添加它之前,它发送了错误:*** 由于未捕获的异常“NSUnknownKeyException”而终止应用程序,原因:“[ setValue:forUndefinedKey:]:此类不符合键值编码的键映射视图。 ' ***
  • @HotLicks 关于如何指向包含该属性的对象的示例?
  • 首先确定它是哪个对象,然后复制指向该对象的指针。

标签: ios objective-c properties mapkit protocols


【解决方案1】:

这是关于属性的背景:Encapsulating Data

简而言之,属性是定义 getter 方法、setter 方法和实例变量(也称为 ivar)的快捷方式。

如果你仔细想想,协议中的非自动合成属性是正确的行为,一开始只是有点令人惊讶。协议定义了一个接口,但从不创建代码。

在您的示例中,协议:

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

-mapView-setMapView: 创建一个接口,但不为这些方法创建实现。

有几种方法可以在@implementation 中获取所需的方法。

  1. 在任何实现MapViewDelegate 的类的@implementation 中声明@synthesize mapView;你已经发现了这个。顺便说一句:我会推荐 @synthesize mapView = _mapView;,因为它是自动合成命名 ivar 的方式。
  2. 在任何实现MapViewDelegate 的类的@interface 中声明@property (nonatomic, strong) IBOutlet MKMapView *mapView;
  3. 创建实例方法- (MKMapView *)mapView- (void)setMapView:(MKMapView *)mapView。这是创建属性的旧手动路径。除了定义 getter 和 setter 之外,您还需要创建一个 ivar 来保存该值。 注意:我只是为了完整起见而将其包含在内,这不是推荐。

【讨论】:

  • 谢谢!我使用@synthesize mapView = _mapView; 实现了第一种方法。在我的墙视图控制器中。我现在当然得到了一个值,但我仍然需要努力将该值传递给仍然返回 null 的表视图控制器。
  • @teenyton - “但我仍然需要努力将该值传递给仍返回 null 的表视图控制器” - 将属性放入协议中不会共享它,它只是说任何实现协议的类必须提供这样的属性。你的两个类中的属性是独立的,设置一个不会影响另一个。
猜你喜欢
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多