Denna delen av 99 uppdateras inte längre utan har arkiverats inför framtiden som ett museum.
Här kan du läsa mer om varför.
Mac-nyheter hittar du på Macradion.com och forumet hittar du via Applebubblan.

Arkiveringsproblem i Cocoa...

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1

Den här tråden är löjligt lång, men kan du någon om Cocoa så skulle jag bli hyvens glad om du ville läsa igenom den och se om du förstår mitt problem...

Försöker få ett program att arkivera mitt fina objectsdiagram. Jag har inte fått det att funka så jag har bantat ner problemet till två objekt.

Såhär ser problemet ut:
Jag har ett objekt Person som har tre instansvariabler:

NSString *personName;
int personAge;
Book *personBook;

Book i sin tur har två instansvariabler:

NSString *bookTitle;
int pageCount;

Eftersom man ska "lära" objekten att arkivera sig själva har jag implementerat <NSCoding> - protokollet till både Person och Book. Jag har implementerat

- (void)encodeWithCoder:(NSCoder *)coder

och

- (id)initWithCoder:(NSCoder *)coder

hos båda objekten.

Själva programmet består av en NSMutableArray som lagrar ett antal person-object och presenterar dem i en NSTableView.

Jag har implementerat följande metoder för at t starta arkivering samt laddning av de sparade filerna:

- (NSData)dataRepresentationOfType:(NSString *)aType
{
[tableView deselectAll:nil];
return [NSArchiver archivedDataWithRootObject:students];
}

samt

- (BOOL)loadDataRepresentation:(NSData * data ofType:(NSString *)aType
{
[students release];
students = [[NSUnarchiver unarchiveObjectWithData:data] retain];
[self updateUI];
return YES;
}

Allt verkar funka finfint. Jag kan spara mitt dokument och det verkar funka bra. Men när jag öppnar filen igen (jag har följt arbetsgången med debuggern) så läser den in alla objekt (även Book) men precis när den lämnar funktionen...

students = [[NSUnarchiver unarchiveObjectWithData:data] retain];

...så dealloceras samtliga Book-objekt och programmet krashar med felmeddelandet...

ArchiveringsTest.app has exited due to signal 11 (SIGSEGV).

Mina kunskaper går bet. Någon som förstår vad jag gjort för fel, eller finns det någon som helt enkelt kan tala om för mig hur jag skall göra för att avarkivera bägge objekten?

Tacksam för svar!!!´

/JO

  • Medlem
  • International user
  • 2002-05-05 19:09

Hmm, mysko problem.. Jag har aldrig själv jobbat speciellt mkt med Archiving och Serialization, men har du kollat vad dina Book* objekt har för retainCount när dom avkodats?

Eftersom du laddar in dom så borde dom inte vara autorelease, men man vet ju aldrig.. retainar du alla objekten när dom blir avkodade?

Jag har inte kollat deras retain-count. Borde kanske göra det. Jag har dock aldrig använt mig av autorelease-anropet. Det skulle vara ifall någon fördefinierad cococametod autoreleasar dem... Verkar mysko. Jag testar och ser...

  • Medlem
  • International user
  • 2002-05-06 11:01

Om du inte själv kör alloc och någon initmetod på objektet så blir det autorelease automatiskt. Skriv en metod som går igenom och kollar dina releaseCount.. Alltid bra att ha när man får konstiga fel..

Okej kent! Det verkar som om du hade rätt!

Jag retainade det strulande objektet då jag decodade det.

- (id)initWithCoder:(NSCoder *)coder
{
if(self = [super init])
{
[self setPersonName:[coder decodeObject]];
personBook = [[coder decodeObject] retain];
[coder decodeValueOfObjCType:@encode(int) at:&personAge];
}
return self;
}

...och nu funkar allt finfint!!!
_______________________________

Nu har jag bara ett par frågor.

Citat:

quote:
Om du inte själv kör alloc och någon initmetod på objektet så blir det autorelease automatiskt.

I initieringsmetoden för Person har jag allocerat och initierat Book-objektet enligt följande:

@implementation Person

- (id)init
{
if(self = [super init]);
{
[self setPersonName:@New Student];
[self setPersonAge:18];
personBook = [[Book alloc]init];
}
return self;
}

Där Book init ser ut på följande sätt:

- (id)init
{
if(self = [super init])
{
[self setBookTitle:@Calculus];
[self setPageCount:800];
}
return self;
}

Är det detta du menar med att "köra alloc och någon initmetod på objektet"? Om inte? Vad är det som krävs för att objektet inte skall bli autoreleasat per default?

Citat:

quote:
Skriv en metod som går igenom och kollar dina releaseCount.

Hur skall en sådan metod se ut?

Tack så oerhört för hjälpen!! Det är så tarvligt när man kör fast!!

/Jont Olof

  • Medlem
  • International user
  • 2002-05-06 18:30
Citat:

quote:Är det detta du menar med att "köra alloc och någon initmetod på objektet"? Om inte? Vad är det som krävs för att objektet inte skall bli autoreleasat per default?

Det var exakt vad jag menade.. Det objektet måste du själv köra release på när det ska bort, annars kommer det inte försvinna förens programmet avslutas.

Citat:

quote:

Citat:

quote:Skriv en metod som går igenom och kollar dina releaseCount.



Hur skall en sådan metod se ut?

Det beror alltid på lite..
- (void)printDebugInfo {
NSLog(@"Debugging: %@(%u):%p {", NSStringFromClass([self class]), [self retainCount], self);
NSLog(@"Members:");

NSLog(@"mIntVariabel: %d", mIntVariabel);
NSLog(@"mObjCObjekt: %@(%u)", mObjCObjekt, [mObjCObjekt retainCount]);

[student printDebugInfo];
[book printDebugInfo];

NSLog(@"} //%@", NSStringFromClass([self class]));
}

Det här var bara ett exempel, du får ändra det till det du tycker verkar vettigt att veta..

Tack kent! Lysande! Jag skall testa det här när jag får möjlighet!!

/JO

1
Bevaka tråden