NSCoding 与对象内的 NSString
Posted
技术标签:
【中文标题】NSCoding 与对象内的 NSString【英文标题】:NSCoding with as NSString inside a object 【发布时间】:2011-03-28 22:22:38 【问题描述】:然后我的问题是我检索了 Store
对象的 NSArray,我的所有 NSString 属性都导致 BadAccess
错误。 int 和 double 属性工作正常!
store.h
@interface Store : NSObject<NSCoding>
NSString *Name;
NSString *Address;
NSString *Phone;
double GeoLong;
double GeoLat;
int ID;
@property (nonatomic, retain) NSString *Name;
@property (nonatomic, retain) NSString *Address;
@property (nonatomic, retain) NSString *Phone;
@property (nonatomic) double GeoLat;
@property (nonatomic) double GeoLong;
@property (nonatomic) int ID;
@end
store.m
@implementation Store
@synthesize Name;
@synthesize ID;
@synthesize Address;
@synthesize Phone;
@synthesize GeoLat;
@synthesize GeoLong;
/** Implentation of the NSCoding protocol. */
-(void)encodeWithCoder:(NSCoder *)encoder
[encoder encodeInt:ID forKey:@"ID"];
[encoder encodeDouble:GeoLat forKey:@"GeoLat"];
[encoder encodeDouble:GeoLong forKey:@"GeoLong"];
NSLog(@"Name in encode: %@", Name); //WORKS!
[encoder encodeObject:Name forKey:@"Name"];
[encoder encodeObject:Phone forKey:@"Phone"];
[encoder encodeObject:Address forKey:@"Address"];
-(id)initWithCoder:(NSCoder *)decoder
// Init first.
if(self = [self init])
ID = [decoder decodeIntForKey:@"ID"];
GeoLat = [decoder decodeDoubleForKey:@"GeoLat"];
GeoLong = [decoder decodeDoubleForKey:@"GeoLong"];
Name = [decoder decodeObjectForKey:@"Name"];
NSLog(@"Name in decode: %@", Name); //WORKS! logs the name
Address = [decoder decodeObjectForKey:@"Address"];
Phone = [decoder decodeObjectForKey:@"Phone"];
return self;
- (void)dealloc
[Name release];
[ID release];
[Address release];
[Phone release];
[super dealloc];
@end
这是我用于存储和检索数组的代码。
//streams contains the data i will populate my array with.
for (ndx = 0; ndx < streams.count; ndx++)
NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:ndx];
Store *item = [[Store alloc] init] ;
item.Name = [stream valueForKey:@"Name"];
item.Address = [stream valueForKey:@"Address"];
item.Phone = [stream valueForKey:@"Phone"];
item.GeoLat = [[stream valueForKey:@"GeoLat"] doubleValue];
item.GeoLong = [[stream valueForKey:@"GeoLong"] doubleValue];
item.ID = [[stream valueForKey:@"ID"] intValue];
[listToReturn addObject:item];
//test to check if it works
for(int i = 0; i < [listToReturn count]; i++)
Store *item = (Store *)[listToReturn objectAtIndex:i];
NSLog(@"Name: %@", item.Name); //works
//save
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:listToReturn] forKey:@"stores"];
// retrieve
NSMutableArray *stores = [NSMutableArray new];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"stores"];
if (dataRepresentingSavedArray != nil)
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if (oldSavedArray != nil)
stores = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
stores = [[NSMutableArray alloc] init];
if ([stores count] > 0)
NSMutableArray * annotations = [[NSMutableArray alloc] init];
for(int i = 0;i< [stores count]; i++)
Store *store = [stores objectAtIndex: i];
CLLocationCoordinate2D location;
if(store.GeoLat != 0 && store.GeoLong != 0)
location.latitude = store.GeoLat;
location.longitude = store.GeoLong; //works
NSLog(@"Adding store: %@", store.Name); //DONT WORK!! <-- MAIN PROBLEM
感觉我什么都试过了,但不知道它在解码中是如何工作的,但在我把它放入数组后循环数组时却不知道。
有人有什么想法吗?
【问题讨论】:
嘿,我意识到这与手头的问题无关,只是仅供参考。以大写字母开头的变量名违反了所有样式指南。 在objective-c中,您的ivars应该在第一个字母上使用小写字母,而类应该在第一个字母上使用大写字母......只是一个约定。 【参考方案1】:您没有保留initWithCoder
中的属性。
Name = [decoder decodeObjectForKey:@"Name"];
没有使用您定义的(保留)属性的设置器。您只是在设置 ivar。这意味着您不会获得所有权,并且可以将其解除分配。
您可以通过以下两种方式保留案例中的属性:
self.Name = [decoder decodeObjectForKey:@"Name"];
Name = [[decoder decodeObjectForKey:@"Name"] retain];
【讨论】:
太棒了,太棒了,你也是 :) 良好而丰富的解释 :) 正是我想要的 :)以上是关于NSCoding 与对象内的 NSString的主要内容,如果未能解决你的问题,请参考以下文章
包含自定义对象的 NSMutableDictionaries 的 NSCoding