2011-07-04 11 views
5

Blokuję coś i jestem pewien, że jest za duży. Mam niestandardowego obiektu, który wyglądał takNapisz niestandardowy obiekt do .plist w kakao

@interface DownloadObject : NSObject <NSCoding>{ 
    NSNumber *key; 
    NSString *name; 
    NSNumber *progress; 
    NSNumber *progressBytes; 
    NSNumber *size; 
    NSString *path; 
} 
@property (copy) NSNumber *key; 
@property (copy) NSString *name; 
@property (copy) NSNumber *progress; 
@property (copy) NSNumber *size; 
@property (copy) NSString *path; 
@property (copy) NSNumber *progressBytes; 
-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb; 
@end 

i wdrożenie

@implementation DownloadObject 
@synthesize size, progress, name, key, path, progressBytes; 

-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb 
{ 
    self.key = k; 
    self.name = n; 
    self.progress = pro; 
    self.size = s; 
    self.path = p; 
    self.progressBytes = pb; 

    return self; 
} 

-(id) initWithCoder: (NSCoder*) coder { 
    if (self = [super init]) { 
     self.key = [[coder decodeObjectForKey:@"Key"] retain]; 
     self.name = [[coder decodeObjectForKey:@"Name"] retain]; 
     self.progress = [[coder decodeObjectForKey:@"Progress"] retain]; 
     self.size = [[coder decodeObjectForKey:@"Size"] retain]; 
     self.path = [[coder decodeObjectForKey:@"Path"] retain]; 
     self.progressBytes = [[coder decodeObjectForKey:@"ProgressBytes"]retain]; 
    } 
    return self; 
} 


-(void) encodeWithCoder: (NSCoder*) coder { 
    [coder encodeObject:self.key forKey:@"Key"]; 
    [coder encodeObject:self.name forKey:@"Name"]; 
    [coder encodeObject:self.progress forKey:@"Progress"]; 
    [coder encodeObject:self.size forKey:@"Size"]; 
    [coder encodeObject:self.path forKey:@"Path"]; 
    [coder encodeObject:self.progressBytes forKey:@"ProgressBytes"]; 
} 


-(void)dealloc 
{ 
    [key release]; 
    [name release]; 
    [size release]; 
    [progress release]; 
    [path release]; 
    [progressBytes release]; 
    [super dealloc]; 
} 

@end 

Jak widać to wdrożyć NSCoding (myślę więc, NSObject nie odpowiada NSCoding). Teraz, gdy próbuję zrobić coś takiego tylko do testowania

downloadArray = [[[NSMutableArray alloc]init]retain]; 
NSNumber *number = [NSNumber numberWithInt:10]; 
DownloadObject *object = [[DownloadObject alloc]initWithKey:number name:@"hey" progress:number size:number path:@"hey" progressBytes:number]; 
[downloadArray addObject:object]; 
[object release]; 
[downloadArray writeToFile:path atomically:YES]; 

downloadArray jest NSMutableArray. Mój plist odczyt/zapis jest w porządku, path znajduje się w obsłudze aplikacji, a po jego zalogowaniu pokazuje ścieżkę plist.

Ale po prostu nie zapisuje tablicy do plist, żadnego pomysłu?

+0

Dlaczego ustawiasz wartość retain na DownloadArray na 2? Wymagane tylko \t downloadArray = [[NSMutableArray alloc] init]; –

Odpowiedz

0

Działa to dla mnie: lista plików

NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 

[archiver encodeObject:highScoreArray forKey:kHighScoreArrayKey]; 

[archiver finishEncoding]; 

[data writeToFile:[self dataFilePath] atomically:YES]; 

[data release]; 
[archiver release]; 
21

nieruchomość może przechowywać tylko podstawowe typy danych i nie mogą zawierać niestandardowych obiektów. Musisz przekonwertować obiekt na obiekt NSData, jeśli chcesz, aby był zapisany w pliku plist. Możesz to zrobić za pomocą NSKeyedArchiver, który zakoduje obiekt, który jest zgodny z protokołem NSCoding, w obiekt NSData.

DownloadObject *object = [[DownloadObject alloc]initWithKey:number name:@"hey" progress:number size:number path:@"hey" progressBytes:number]; 
NSData* objData = [NSKeyedArchiver archivedDataWithRootObject:object]; 
[downloadArray addObject:objData]; 
[object release]; 

Gdy chcesz odtworzyć swój obiekt z obiektu NSData, należy użyć NSKeyedUnarchiver:

NSData* objData = [downloadArray objectAtIndex:0]; 
DownloadObject* object = [NSKeyedUnarchiver unarchiveObjectWithData:objData]; 

Trzeba także kilka wycieków pamięci w kodzie. W swojej metodzie -initWithCoder:, nie powinien używać akcesorów, aby ustawić wartość Ivars, należy po prostu ustawić Ivars bezpośrednio, tak jak poniżej:

key = [[coder decodeObjectForKey:@"Key"] copy]; 

Telefonujesz -retain a następnie za pomocą akcesor który jest określony jako copy, co oznacza, że ​​obiekt ma wartość zatrzymania 2 i nie zostanie zwolniony. Generalnie powinieneś unikać używania akcesorów w metodach init.

Również w kodzie gdzie zainwestować swój obiekt downloadArray, dzwonisz -alloc a następnie -retain na obiekcie, który pozostawi go z retainCount z 2. Należy ponownie odczytać Objective-C Memory Management Guidelines.

+0

czy warto? Chodzi mi o to, czy jest to bardziej produktywne niż po prostu przekształcenie właściwości w słownik i zapisanie jako słownik? Dlaczego potrzebuję zawinąć mój obiekt do nsdata lub czy są jakieś zalecenia na ten temat? –

0
BOOL flag = false; 

    ObjectFileClass *obj = [yourMutableArray objectAtIndex:0]; 

    //TO Write Data . . . 

    NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:obj.title]; 
    flag =[archiveData writeToFile:path options:NSDataWritingAtomic error:&error]; 
} 


if (flag) { 
    NSLog(@"Written"); 

    //To Read Data . . . 

    NSData *archiveData = [NSData dataWithContentsOfFile:path]; 
    id yourClassInstance = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; // choose the type of your class instance . . . 
    NSLog(@"%@",yourClassInstance); 
}else{ 

    NSLog(@"Not Written"); 
}