循环遍历 NSDictionary 从属性列表中读入证明很麻烦

发布于 2024-10-04 07:21:55 字数 7415 浏览 3 评论 0原文

大家好,我正在从一个如下结构的 plist 中读取:

property list

如您所见,这是一个 plist包含不同类型(C,Visitor)的注释信息。我可以很好地显示每种注释类型,但我试图循环遍历所有类型并立即在地图视图上显示所有注释。这是代码:

NSLog(@"loadAnnotations");
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"PermitData" ofType:@"plist"];
NSDictionary *rootOfPermitDataPlistDict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
// NSMutableDictionary *permitDict = [[NSMutableDictionary alloc] init];
 if ([self title] == @"All Permits") {
  for (id key in rootOfPermitDataPlistDict) {
   NSLog(@"key:%@",key);

   //[key retain];
   NSMutableDictionary *permitDict = [NSDictionary dictionaryWithDictionary:[rootOfPermitDataPlistDict objectForKey:key]];
   //[key release];

   //array containing annotation information: latitude, longitude, title, subtitle(see PermitData.plist)
   NSArray *annotationsArray = [[NSArray alloc] initWithArray:[permitDict objectForKey:@"annotations"]];
   [permitDict release];
   [rootOfPermitDataPlistDict release];

   CLLocationCoordinate2D workingCoordinate;
   NSDictionary *annotationContainerDict = [[NSDictionary alloc] init];
   //loop through annotations array, creating parking annotations filled with the information found in the plist
   for(annotationContainerDict in annotationsArray){
    NSLog(@"%@",annotationContainerDict);

    ParkingAnnotation *parkingAnnot = [[ParkingAnnotation alloc] init];
    workingCoordinate.latitude = [[annotationContainerDict objectForKey:@"latitude"] doubleValue];
    workingCoordinate.longitude = [[annotationContainerDict objectForKey:@"longitude"] doubleValue];
    [parkingAnnot setCoordinate:workingCoordinate];
    [parkingAnnot setTitle:[annotationContainerDict objectForKey:@"title"]];
    [parkingAnnot setSubtitle:[annotationContainerDict objectForKey:@"subtitle"]];
    if ([parkingAnnot title] == @"C Parking") [parkingAnnot setAnnotationType:annotationTypeC];
    else if ([parkingAnnot title] == @"Visitor Parking") [parkingAnnot setAnnotationType:annotationTypeVisitor];
    [mapView addAnnotation:parkingAnnot];
    [parkingAnnot release];
   }
   [permitDict release];
  }
 }

这是我运行程序时的控制台输出:

2010-11-25 03:25:28.020 Parking[38918:207] All Permits
2010-11-25 03:25:28.021 Parking[38918:207] loadAnnotations
2010-11-25 03:25:28.021 Parking[38918:207] key:C
2010-11-25 03:25:28.021 Parking[38918:207] {
    latitude = "38.545301";
    longitude = "-121.754066";
    subtitle = "VP 17";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544831";
    longitude = "-121.754785";
    subtitle = "VP 16";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544781";
    longitude = "-121.755729";
    subtitle = "VP 22";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544412";
    longitude = "-121.752489";
    subtitle = "VP 15";
    title = "C Parking";
}

因此它正确地循环第一个 NSDictionary,但在即将开始循环下一个时崩溃。我尝试将 NSDictionary 更改为 NSMutableDictionary 但结果是相同的。因此,当我在表视图中选择“所有许可”行时,它会挂起几分之一秒(不切换到地图视图),然后崩溃,而不会生成错误。

如果有人不介意在这里帮助我,我将不胜感激。提前致谢!

编辑: 这是堆栈跟踪(在下面的注释中描述):

2010-11-25 20:28:08.141 Parking[39400:207] All Permits
2010-11-25 20:28:08.142 Parking[39400:207] loadAnnotations
2010-11-25 20:28:08.142 Parking[39400:207] key:C
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.545301";
    longitude = "-121.754066";
    subtitle = "VP 17";
    title = "C Parking";
}
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.544831";
    longitude = "-121.754785";
    subtitle = "VP 16";
    title = "C Parking";
}
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.544781";
    longitude = "-121.755729";
    subtitle = "VP 22";
    title = "C Parking";
}
2010-11-25 20:28:08.144 Parking[39400:207] {
    latitude = "38.544412";
    longitude = "-121.752489";
    subtitle = "VP 15";
    title = "C Parking";
}
2010-11-25 20:28:08.145 Parking[39400:207] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x6d5fd80> was mutated while being enumerated.<CFBasicHash 0x6d5fd80 [0x2667380]>{type = mutable dict, count = 1,
entries =>
    0 : <0x7380> = <NSKeyValueContainerClass: Original class: ParkingAnnotation, Notifying class: NSKVONotifying_ParkingAnnotation>
}
'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x025fdb99 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0274d40e objc_exception_throw + 47
    2   CoreFoundation                      0x025fd659 __NSFastEnumerationMutationHandler + 377
    3   Parking                             0x00002e93 -[ParkingMapViewController loadAnnotations] + 364
    4   Parking                             0x00002caf -[ParkingMapViewController viewDidLoad] + 117
    5   UIKit                               0x0036a5ca -[UIViewController view] + 179
    6   UIKit                               0x003689f4 -[UIViewController contentScrollView] + 42
    7   UIKit                               0x003787e2 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
    8   UIKit                               0x00376ea3 -[UINavigationController _layoutViewController:] + 43
    9   UIKit                               0x00378067 -[UINavigationController _startTransition:fromViewController:toViewController:] + 326
    10  UIKit                               0x00372ccd -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    11  UIKit                               0x00379d8b -[UINavigationController pushViewController:transition:forceImmediate:] + 876
    12  UIKit                               0x00372b67 -[UINavigationController pushViewController:animated:] + 62
    13  Parking                             0x00002914 -[PermitListViewController tableView:didSelectRowAtIndexPath:] + 307
    14  UIKit                               0x00333a48 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    15  UIKit                               0x0032a32e -[UITableView _userSelectRowAtIndexPath:] + 219
    16  Foundation                          0x0003f21a __NSFireDelayedPerform + 441
    17  CoreFoundation                      0x025def73 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    18  CoreFoundation                      0x025e05b4 __CFRunLoopDoTimer + 1364
    19  CoreFoundation                      0x0253cdd9 __CFRunLoopRun + 1817
    20  CoreFoundation                      0x0253c350 CFRunLoopRunSpecific + 208
    21  CoreFoundation                      0x0253c271 CFRunLoopRunInMode + 97
    22  GraphicsServices                    0x02edc00c GSEventRunModal + 217
    23  GraphicsServices                    0x02edc0d1 GSEventRun + 115
    24  UIKit                               0x002ceaf2 UIApplicationMain + 1160
    25  Parking                             0x00001e08 main + 102
    26  Parking                             0x00001d99 start + 53
)
terminate called after throwing an instance of 'NSException'

但是,我在 for 循环中释放了 PermitDict(第二个 [permitDict release] 未注释),所以我不知道为什么它抱怨 NSDictionary 是不可变的。正如你所看到的,permitDict 是 NSMutableDictionary 类型,所以我不明白为什么它会给我这个错误。

Ey guys, I am reading in from a plist structured like so:

property list

As you can see, it is a plist that contains annotation information of different types(C,Visitor). I can display each annotation type just fine, but I am attempting to loop through all types and display all annotations on the map view at once. Here is the code:

NSLog(@"loadAnnotations");
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"PermitData" ofType:@"plist"];
NSDictionary *rootOfPermitDataPlistDict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
// NSMutableDictionary *permitDict = [[NSMutableDictionary alloc] init];
 if ([self title] == @"All Permits") {
  for (id key in rootOfPermitDataPlistDict) {
   NSLog(@"key:%@",key);

   //[key retain];
   NSMutableDictionary *permitDict = [NSDictionary dictionaryWithDictionary:[rootOfPermitDataPlistDict objectForKey:key]];
   //[key release];

   //array containing annotation information: latitude, longitude, title, subtitle(see PermitData.plist)
   NSArray *annotationsArray = [[NSArray alloc] initWithArray:[permitDict objectForKey:@"annotations"]];
   [permitDict release];
   [rootOfPermitDataPlistDict release];

   CLLocationCoordinate2D workingCoordinate;
   NSDictionary *annotationContainerDict = [[NSDictionary alloc] init];
   //loop through annotations array, creating parking annotations filled with the information found in the plist
   for(annotationContainerDict in annotationsArray){
    NSLog(@"%@",annotationContainerDict);

    ParkingAnnotation *parkingAnnot = [[ParkingAnnotation alloc] init];
    workingCoordinate.latitude = [[annotationContainerDict objectForKey:@"latitude"] doubleValue];
    workingCoordinate.longitude = [[annotationContainerDict objectForKey:@"longitude"] doubleValue];
    [parkingAnnot setCoordinate:workingCoordinate];
    [parkingAnnot setTitle:[annotationContainerDict objectForKey:@"title"]];
    [parkingAnnot setSubtitle:[annotationContainerDict objectForKey:@"subtitle"]];
    if ([parkingAnnot title] == @"C Parking") [parkingAnnot setAnnotationType:annotationTypeC];
    else if ([parkingAnnot title] == @"Visitor Parking") [parkingAnnot setAnnotationType:annotationTypeVisitor];
    [mapView addAnnotation:parkingAnnot];
    [parkingAnnot release];
   }
   [permitDict release];
  }
 }

And this is the console output when I run the program:

2010-11-25 03:25:28.020 Parking[38918:207] All Permits
2010-11-25 03:25:28.021 Parking[38918:207] loadAnnotations
2010-11-25 03:25:28.021 Parking[38918:207] key:C
2010-11-25 03:25:28.021 Parking[38918:207] {
    latitude = "38.545301";
    longitude = "-121.754066";
    subtitle = "VP 17";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544831";
    longitude = "-121.754785";
    subtitle = "VP 16";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544781";
    longitude = "-121.755729";
    subtitle = "VP 22";
    title = "C Parking";
}
2010-11-25 03:25:28.022 Parking[38918:207] {
    latitude = "38.544412";
    longitude = "-121.752489";
    subtitle = "VP 15";
    title = "C Parking";
}

So it loops through the first NSDictionary properly, but crashes when it is about to begin looping through the next one. And I have tried changing NSDictionary to NSMutableDictionary but the result is the same. So when I select the "All Permits" row in the table view, it hangs for a fraction of a second(without switching to the map view), and then crashes, without generating an error.

If anyone wouldn't mind helping me out here, I would greatly appreciate it. Thanks in advance!

EDIT:
Here is the stack trace(described in comments below):

2010-11-25 20:28:08.141 Parking[39400:207] All Permits
2010-11-25 20:28:08.142 Parking[39400:207] loadAnnotations
2010-11-25 20:28:08.142 Parking[39400:207] key:C
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.545301";
    longitude = "-121.754066";
    subtitle = "VP 17";
    title = "C Parking";
}
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.544831";
    longitude = "-121.754785";
    subtitle = "VP 16";
    title = "C Parking";
}
2010-11-25 20:28:08.143 Parking[39400:207] {
    latitude = "38.544781";
    longitude = "-121.755729";
    subtitle = "VP 22";
    title = "C Parking";
}
2010-11-25 20:28:08.144 Parking[39400:207] {
    latitude = "38.544412";
    longitude = "-121.752489";
    subtitle = "VP 15";
    title = "C Parking";
}
2010-11-25 20:28:08.145 Parking[39400:207] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x6d5fd80> was mutated while being enumerated.<CFBasicHash 0x6d5fd80 [0x2667380]>{type = mutable dict, count = 1,
entries =>
    0 : <0x7380> = <NSKeyValueContainerClass: Original class: ParkingAnnotation, Notifying class: NSKVONotifying_ParkingAnnotation>
}
'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x025fdb99 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x0274d40e objc_exception_throw + 47
    2   CoreFoundation                      0x025fd659 __NSFastEnumerationMutationHandler + 377
    3   Parking                             0x00002e93 -[ParkingMapViewController loadAnnotations] + 364
    4   Parking                             0x00002caf -[ParkingMapViewController viewDidLoad] + 117
    5   UIKit                               0x0036a5ca -[UIViewController view] + 179
    6   UIKit                               0x003689f4 -[UIViewController contentScrollView] + 42
    7   UIKit                               0x003787e2 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
    8   UIKit                               0x00376ea3 -[UINavigationController _layoutViewController:] + 43
    9   UIKit                               0x00378067 -[UINavigationController _startTransition:fromViewController:toViewController:] + 326
    10  UIKit                               0x00372ccd -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    11  UIKit                               0x00379d8b -[UINavigationController pushViewController:transition:forceImmediate:] + 876
    12  UIKit                               0x00372b67 -[UINavigationController pushViewController:animated:] + 62
    13  Parking                             0x00002914 -[PermitListViewController tableView:didSelectRowAtIndexPath:] + 307
    14  UIKit                               0x00333a48 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    15  UIKit                               0x0032a32e -[UITableView _userSelectRowAtIndexPath:] + 219
    16  Foundation                          0x0003f21a __NSFireDelayedPerform + 441
    17  CoreFoundation                      0x025def73 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    18  CoreFoundation                      0x025e05b4 __CFRunLoopDoTimer + 1364
    19  CoreFoundation                      0x0253cdd9 __CFRunLoopRun + 1817
    20  CoreFoundation                      0x0253c350 CFRunLoopRunSpecific + 208
    21  CoreFoundation                      0x0253c271 CFRunLoopRunInMode + 97
    22  GraphicsServices                    0x02edc00c GSEventRunModal + 217
    23  GraphicsServices                    0x02edc0d1 GSEventRun + 115
    24  UIKit                               0x002ceaf2 UIApplicationMain + 1160
    25  Parking                             0x00001e08 main + 102
    26  Parking                             0x00001d99 start + 53
)
terminate called after throwing an instance of 'NSException'

However, I am releasing permitDict within the for loop(second [permitDict release] was left uncommented), so I don't know why it is complaining about the NSDictionary being immutable. As you can see, the permitDict is of type NSMutableDictionary, so I am lost as to why it is giving me this error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长不大的小祸害 2024-10-11 07:21:55

该代码崩溃的主要原因有两个。

首先,for循环内的这一行:

[rootOfPermitDataPlistDict release];

销毁当前正在循环的对象。将其移至最后 - 在 if ([self title]... 语句的右大括号之后。

以下两行:

[permitDict release];

第二,应删除 不要释放permitDict,因为您正在使用dictionaryWithDictionary 创建它,它返回一个自动释放的对象,

通过这两个更改,代码应该运行。


However, there are a few other problems:

  • 您分配+init annotationsArray 但从未释放它(内存泄漏)。在遍历该数组的 for 循环之后释放它(当前有第二个 [permitDict release];)。
  • 您分配+ init annotationContainerDict,但随后仅使用该变量作为对annotationsArray中对象的引用(因此放弃分配的内存 - 内存泄漏)。不必费心对annotationContainerDict 进行alloc+init,只需声明它即可。将 NSDictionary *annotationContainerDict = [[NSDictionary alloc] init]; 更改为 NSDictionary *annotationContainerDict;
  • 您正在使用 == 比较字符串。使用 isEqualToString: 代替,如下所示:
    if ([[self title] isEqualToString:@"All Permits"])...。有关为什么应使用 isEqualToString 的说明,请参阅此问题这个问题
  • 这里并不是一个真正严重的问题,但没有必要使用dictionaryWithDictionary,从而复制 rootOfPermitDataPlistDict 中已有的内容。您可以使用 PermitDict 作为嵌入字典的速记引用,如下所示:NSMutableDictionary *permitDict = [rootOfPermitDataPlistDict objectForKey:key];
  • 与annotationsArray相同的一点:你不需要分配+初始化一个新数组。该数组已位于 rootOfPermitDataPlistDict 中。只需像这样获取对它的引用:NSArray *annotationsArray = [permitDict objectForKey:@"annotations"];。如果您决定这样做,请不要释放annotationsArray。

内存管理编程指南解释了所有内容这个详细。

The code is crashing for two main reasons.

First, this line which is inside the for-loop:

[rootOfPermitDataPlistDict release];

destroys the very object that you're currently looping through. Move it to the very end--after the closing brace of the if ([self title]... statement.

Second, the two lines that say:

[permitDict release];

should be removed. Do not release permitDict because you are creating it using dictionaryWithDictionary which returns an autoreleased object.

With those two changes, the code should run.


However, there are a few other problems:

  • You alloc+init annotationsArray but never release it (memory leak). Release it after the for-loop that goes through that array (where you currently have the second [permitDict release];).
  • You alloc+init annotationContainerDict but then use the variable only as a reference to the objects in the annotationsArray (and so abandoning the allocated memory--memory leak). Don't bother doing alloc+init on annotationContainerDict, just declare it. Change NSDictionary *annotationContainerDict = [[NSDictionary alloc] init]; to just NSDictionary *annotationContainerDict;.
  • You are comparing strings using ==. Use isEqualToString: instead like this:
    if ([[self title] isEqualToString:@"All Permits"]).... For an explanation of why you should use isEqualToString, see this question and this question.
  • Not really a serious problem here but it is unnecessary to use dictionaryWithDictionary and thus duplicating what's already there in rootOfPermitDataPlistDict. You could just use permitDict as a shorthand reference to the embedded dictionary like this: NSMutableDictionary *permitDict = [rootOfPermitDataPlistDict objectForKey:key];.
  • Same point with annotationsArray: you don't need to alloc+init a new array. The array is already in rootOfPermitDataPlistDict. Just get a reference to it like this: NSArray *annotationsArray = [permitDict objectForKey:@"annotations"];. Do not release annotationsArray if you decide to do it this way.

The Memory Management Programming Guide explains all this in detail.

吲‖鸣 2024-10-11 07:21:55

首先,您的代码存在很多问题,但除非这是性能关键的代码,否则您将每秒循环数百次(这可能会创建许多自动释放的对象),否则使用 alloc] init] 方法只会使代码更难遵循。 (因为您必须在心里仔细考虑并不断平衡分配与释放)。不要误会我的意思,理解保留和释放等很重要,但这就是我解决问题的方式。

请记住,一切尽在您的掌控之中。让你的停车注释类能够“自己思考”一点。在下面的示例中,我添加了一个 -(id)initWithDictionary: ,这样您的其他类就不必坐在那里并完成一一设置键的所有繁重工作。 (有一些虚构的部分,我假设你会填补空白......

NSString * const PPAnnotationsKey   = @"annotations";
NSString * const PPTitleKey         = @"title";
NSString * const PPSubtitleKey      = @"subtitle";
NSString * const PPLatitudeKey      = @"latitude";
NSString * const PPLongitudeKey     = @"longitude";

NSLog(@"loadAnnotations");
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"PermitData" ofType:@"plist"]; // autoreleased
NSDictionary *permitDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath]; // autoreleased
if ([[self title] isEqualToString:@"All Permits"]) {
    for (NSString *parkingGroup in permitDictionary) {
        NSLog(@"parkingGroup == %@", parkingGroup);
        NSArray *annotations = [parkingGroup objectForKey:PPAnnotationsKey];
        for (NSDictionary *entry in annotations) {
            PPParkingAnnotation *annotation = [PPParkingAnnotation parkingAnnotationWithDictionary:entry]; // autoreleased
            if (annotation) {
            // assuming here that mapView's addAnnotation: will retain the
            // annotation
            [mapView addAnnotation:annotation]; 
            }
        }
    }
}

@interface PPParkingAnnotation : NSObject <MKAnnotation> {
    CLLocationCoordinate2D   coordinate;
    NSString                *title;
    NSString                *subtitle;
}
+ (id)parkingAnnotationWithDictionary:(NSDictionary *)dictionary;
- (id)initWithDictionary:(NSDictionary *)dictionary;

@properties...
@end

@implementation PPParkingAnnotation

+ (id)parkingAnnotationWithDictionary:(NSDictionary *)dictionary {
    return [[[[self class] alloc] initWithDictionary:dictionary] autorelease];
}

- (id)initWithDictionary:(NSDictionary *)dictionary {
    [self setTitle:[dictionary objectForKey:PPTitleKey]];
    [self setSubtitle:[dictionary objectForKey:PPTitleKey]];
    // and so on.
}

First, there were many issues with your code, but unless this is performance critical code, where you'll be looping hundreds of times a second (which could potentially create many autoreleased objects), using alloc] init] method will just make the code harder to follow. (Since you'll have to mentally go through and continually balance an alloc with a release). Don't get me wrong, it is important that you understand retain and release, etc. but this is the way I would approach the problem.

Remember that you're in control. Make your parking annotation classes be able to "think for themselves" a bit. In the example below, I added an -(id)initWithDictionary: so that your other class doesn't have to sit there and do all the grunt work of setting the keys one by one. (There are some fictional parts where I'd assume you'd fill in the blanks...

NSString * const PPAnnotationsKey   = @"annotations";
NSString * const PPTitleKey         = @"title";
NSString * const PPSubtitleKey      = @"subtitle";
NSString * const PPLatitudeKey      = @"latitude";
NSString * const PPLongitudeKey     = @"longitude";

NSLog(@"loadAnnotations");
NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"PermitData" ofType:@"plist"]; // autoreleased
NSDictionary *permitDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath]; // autoreleased
if ([[self title] isEqualToString:@"All Permits"]) {
    for (NSString *parkingGroup in permitDictionary) {
        NSLog(@"parkingGroup == %@", parkingGroup);
        NSArray *annotations = [parkingGroup objectForKey:PPAnnotationsKey];
        for (NSDictionary *entry in annotations) {
            PPParkingAnnotation *annotation = [PPParkingAnnotation parkingAnnotationWithDictionary:entry]; // autoreleased
            if (annotation) {
            // assuming here that mapView's addAnnotation: will retain the
            // annotation
            [mapView addAnnotation:annotation]; 
            }
        }
    }
}

@interface PPParkingAnnotation : NSObject <MKAnnotation> {
    CLLocationCoordinate2D   coordinate;
    NSString                *title;
    NSString                *subtitle;
}
+ (id)parkingAnnotationWithDictionary:(NSDictionary *)dictionary;
- (id)initWithDictionary:(NSDictionary *)dictionary;

@properties...
@end

@implementation PPParkingAnnotation

+ (id)parkingAnnotationWithDictionary:(NSDictionary *)dictionary {
    return [[[[self class] alloc] initWithDictionary:dictionary] autorelease];
}

- (id)initWithDictionary:(NSDictionary *)dictionary {
    [self setTitle:[dictionary objectForKey:PPTitleKey]];
    [self setSubtitle:[dictionary objectForKey:PPTitleKey]];
    // and so on.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文