NSCoding 在对象内使用 NSString
我的问题是,然后我检索 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
}
}
}
感觉就像我尝试了一切,但无法弄清楚它在解码中如何工作,但在将其放入数组后循环数组时却无法弄清楚。
有人有什么想法吗?
My issue is then I retrieve my NSArray of Store
objects, all my NSString properties are causing BadAccess
errors. The int and double properties work fine!
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
Here is my code for storing and retriving the array.
//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
}
}
}
Feels like I tried everything but can't figure out how it works in the decode but not when in loop the array after I put it into a array.
Anyone have any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您没有保留
initWithCoder
中的属性。没有使用您定义的(保留)属性的设置器。你只是设置了ivar。这意味着您不会获得所有权,并且可以取消分配。
您可以通过以下两种方式保留您的案例中的属性:
You're not retaining the properties in
initWithCoder
.is not using the setter of the (retaining) property you've defined. You're just setting the ivar. That means you don't acquire ownership and it can be deallocated.
Here are two ways you can retain the properties in your case: