将CLPlacemark扩展为EXC BAD ACCESS

虽然在这里发现了一个类似的问题,但它并没有提供答案,至less不是针对一般问题。

我的问题是:由于CoreLocation地理编码速度有限,而且我正在开发应用程序的(web-)服务提供了自己的后备地址parsing服务,所以我想使用此自定义地理编码服务以防万一达到Apple的速率限制。 此外,我觉得避免自定义数据types对于由此自定义REST API返回的结果是CLPlacemark的,因此希望使用返回的数据来生成CLPlacemark 。 但是,文档指出CLPlacemark属性(如location, locality, administrativeArea等)是read-only 。 因此,我创build了一个CLPlacemark的子类,将需要的属性合成到我可以访问的私有variables上,即:

 // interface: (.h) @interface CustomPlacemark : CLPlacemark - (nonnull id)initWithLocation: (nonnull CLLocation *)location locality: (nullable NSString *)locality administrativeArea: (nullable NSString *)adminArea country: (nullable NSString *)country; @end // implementation (.m) @implementation CustomPlacemark @synthesize location = _location; @synthesize locality = _locality; @synthesize country = _country; @synthesize administrativeArea = _administrativeArea; - (nonnull id)initWithLocation: (nonnull CLLocation *)location locality: (nullable NSString *)locality administrativeArea: (nullable NSString *)adminArea country: (nullable NSString *)country{ self = [super init]; if(self){ _location = location; _locality = locality; _administrativeArea = adminArea; _country = country; } return self; } @end 

用一个unit testing来testing这个代码,该testingparsing来自JSON文件的数据,并在testing结束时调用带有数据的initWithLocation: locality: administrativeArea: country:方法导致EXC BAD ACCESS (code=1) }NSLog(@"placemark: %@", customPlacemark);variables指向nil虽然之前的NSLog(@"placemark: %@", customPlacemark); 输出正确的值。 此外,逐行逐行testing显示CustomPlacemark正在工作(即指向正确填充的对象),直到达到testing结束。 对我来说,这表明我的CustomPlacemark的取消分配出了问题 – 但究竟是什么?

任何帮助是极大的赞赏!

作为任何人在这里与类似的问题着陆的参考:

经过一番密集的Google-Fu和深入苹果的消息,似乎延伸CLPlacemark不是意图。

但是,我可以根据这里提供的技巧来实现一个解决方法,它基本上滥用了MKPlacemark扩展CLPlacemark的事实,并提供了一个用自定义数据初始化的方法,即- (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary<NSString *, id> * _Nullable)addressDictionary 。 findaddressDictionary的正确关键字来映射CLPlacemark所需的属性可能需要一些试验和错误,特别是因为ABPerson/Addressfunction已经被iOS 9弃用。我发现的关键是:

 @"City" -> CLPlacemark.city @"State" -> CLPlacemark.administrativeArea @"Country" -> CLPlacemark.country