• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Der Sommer ist da! Laue Nächte, lange Abende im Biergarten und Mücken in Heeresstärke - dazu passend lautet das Thema unseres Fotowettbewerbs im Juni Nachtleben --> Klick

Sind Arrays Objects? Oder wie verschachtel ich Arrays?

Pink_Panter

Jonagold
Registriert
05.07.10
Beiträge
19
Hallo.
Der Titel sagt fast alles.
Ich habe eine plist in der Daten gespeichert sind, bzw. werden.
Die plist enthält mehrere Arrays (Datensätze). In diesen Arrays (Datensätzen) sind dann sowohl einzelne Strings als auch wiederum Arrays (Messungen) vorhanden.
Mein Problem ist, ich versuche die zweite Ebene (Datensatz) zu erzeugen mit einem initWithObjects. Dort werden dann die Strings und Arrays (Messungen) eingetragen. Dabei steigt der Kompiler aber immer aus.
Ich habe das sowohl mit einem NSArray als auch mit einem NSMutableArray probiert.
Die Arrays (Messungen) enthalten teilweise Werte, manche sind aber auch leer und nur so erzeugt: NSArray *aArray;

Hier die Codezeile:
NSMutableArray *startDatenArray = [[NSArray alloc] initWithObjects:groesseTemp,aArray,bArray,cArray,dArray,eArray,fArray,gArray,nil];

Fehlermeldung: Program received signal: “EXC_BAD_ACCESS”.

Danke schonmal für die Tips und Ideen.
 
Ist eines der einzufügenden Objekte eventuell nil? Laß successive immer ein Objekt weg beim Einfügen und schau, bei welchem es knallt.

Eigentlich sollte es kein Problem sein, Arrays als Objekte in Arrays zu schachteln.
 
manche sind aber auch leer und nur so erzeugt: NSArray *aArray;
So erzeugst Du kein Array, sondern nur einen Pointer auf ein Array. Der zeigt aber so erst einmal irgendwo hin. Ein leeres Array erzeugst Du so:
Code:
NSArray *aArray = [NSArray array];

NSMutableArray *startDatenArray = [[NSArray alloc] initWithObjects:groesseTemp,aArray,bArray,cArray,dArray,eArray,fArray,gArray,nil];

Fehlermeldung: Program received signal: “EXC_BAD_ACCESS”.
Da wird dann wohl eins der Arrays irgendwo hin zeigen, wo Du nichts zu suchen hast. Außerdem solltest Du einem NSMutableArray Pointer keine NSArray zuweisen.

MacApple
 
Das mit dem Array erzeugen klappt so wie MacApple das geschrieben hat und ich kann mein Array mit leeren Array befüllen.

Außerdem solltest Du einem NSMutableArray Pointer keine NSArray zuweisen.

MacApple

Kam von dem vielen hin und her Probieren und ist korrigiert.

Danke an alle helfenden Hände
 
Hier noch eine Zusatzfrage:

Wenn ich mein MutableArray (Datensatz), so wie oben beschrieben, mit dem Inhalt einer plst befülle in der weitere Arrays(Messungen) sind, sind die dann auch Mutable? Und wenn nicht, wie kann ich in diese Arrays (Messungen) weitere Daten einfügen? Muss ich etwa alle Arrays neu erzeugen in den Datensatz packen und dann als plist speichern?
Ich habe im Moment das Problem, dass der Compiler aussteigt mit der Meldung:
reason:" '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object' "

Hier ein Code-Schnipsel:
for (i=1;i<([datenTempArray count]-1);i++){ //Array mit einem Messsatz (9 Verschiedene Messungen) Messung 1/9 werden nicht benötigt
int indexTemp=[[datensatzArtTempArray objectAtIndex:1] intValue]; //Index zur Datensatzauswahl
[[[speicherDatenTempArray objectAtIndex:indexTemp] objectAtIndex:i] addObject:[datenTempArray objectAtIndex:i]]; //Messungen aus datenTempArray sollen an Index 1-7(jeweils ein Array) des speicherDatenTempArray angefügt werden.
}
 
Wenn ich mein MutableArray (Datensatz), so wie oben beschrieben, mit dem Inhalt einer plst befülle in der weitere Arrays(Messungen) sind, sind die dann auch Mutable?
Nein, die sind nur mutable, wenn Du sie als NSMutableArray erzeugst. Hinzu kommt, wenn Du die Daten als Propertylist speicherst und später wieder lädst, sind alle Container immutable.

Und wenn nicht, wie kann ich in diese Arrays (Messungen) weitere Daten einfügen? Muss ich etwa alle Arrays neu erzeugen in den Datensatz packen und dann als plist speichern?
Ja, Du müsstest alle Arrays in mutable Arrays umwandeln. Das kannst Du vermeiden, wenn Du die Daten mit der Klasse NSKeyedArchiver archiviert speicherst.

Ich habe im Moment das Problem, dass der Compiler aussteigt mit der Meldung:
reason:" '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object' "
Das ist nicht der Compiler der da aussteigt. Der ist da schon längst fertig mit seiner Arbeit. Es ist Dein Programm, was da aussteigt.

Hier ein Code-Schnipsel:
for (i=1;i<([datenTempArray count]-1);i++){ //Array mit einem Messsatz (9 Verschiedene Messungen) Messung 1/9 werden nicht benötigt
int indexTemp=[[datensatzArtTempArray objectAtIndex:1] intValue]; //Index zur Datensatzauswahl
[[[speicherDatenTempArray objectAtIndex:indexTemp] objectAtIndex:i] addObject:[datenTempArray objectAtIndex:i]]; //Messungen aus datenTempArray sollen an Index 1-7(jeweils ein Array) des speicherDatenTempArray angefügt werden.
}
Damit kann ich nix anfangen.

MacApple
 
OK, wenn das alles immutables sind, erklärt sich der Fehler.
Mit dem NSKeyedArchiver muss ich mich dann mal beschäftigen, wenn ich mehr Zeit habe.
Muss das Prog sowieso umarbeiten, wenn ich vom Simulator aufs iPhone übergehe.

Klar, sorry. Das Prog läuft ja schon, wenn der Fehler auftritt, kann ja nicht der Compiler sein.

Kann ich abfragen, ob das App im Simulator oder auf nem iPhone läuft? Und wenn, dann wie. Wenn möglich zur Erklärung bitte etwas Code dazu geben.

Vielen Dank an die helfenden Hände.
 
Hi.
Wieso ich umarbeiten muss? Im Moment lade und speichere ich meine Daten in einer plist über den Bundle Pfad:
NSString *pfad = [[NSBundle mainBundle] pathForResource:@"DatenTemp" ofType:@"plist"];
Das funktioniert ja auf dem iPhone nicht mehr. Da muss ich ja den Pfad zum App-Dokumenteordner ermitteln und dort speichern/laden.
Das kann ich aber wiederum nicht auf meinem Rechner machen. Ich habe das schonmal versucht, es gibt ja schließlich einen Dokumente Ordner, aber den hat er nie gefunden.
Meine Idee war jetzt eine Abfrage beim Speichern und Laden, welchen Pfad es nehmen soll, je nachdem ob es im Simulator oder auf dem iPhone läuft.
 
Wieso ich umarbeiten muss? Im Moment lade und speichere ich meine Daten in einer plist über den Bundle Pfad:
NSString *pfad = [[NSBundle mainBundle] pathForResource:@"DatenTemp" ofType:@"plist"];
Das funktioniert ja auf dem iPhone nicht mehr. Da muss ich ja den Pfad zum App-Dokumenteordner ermitteln und dort speichern/laden.
Das ist natürlich ein Grund. Besser man fängt mit so etwas gar nicht erst an.

Das kann ich aber wiederum nicht auf meinem Rechner machen. Ich habe das schonmal versucht, es gibt ja schließlich einen Dokumente Ordner, aber den hat er nie gefunden.
Dann hast Du da etwas falsch gemacht:
Code:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(@"%@", [paths objectAtIndex:0]); // Na guck mal ;)
MacApple
 
Sorry,dass ich mich erst jetzt bedanke, war schwer beschäftigt.
Diese Pfadanzeige/-ermittlung funktioniert sowohl auf dem Simulator als auch auf dem Handy? Hat es einen bestimmten Grund, dass du ein Array und keine String als Pfadvariable nutzt?
Meine erstellte Plist mit einigen Testdaten findet das Prog über den Bundle Pfad, und kann die Werte auch auslesen. Nur dauerhaft speichern ist nicht möglich. Liegt das daran, dass Xcode jedesmal eine neues "Projekt" anlegt, wenn ich die Software starte? Damit ändert sich ja auch jedes mal der Document Ordner. Wie kann ich also im Simulator testen, ob gespeicherte Daten nach dem beenden auch wirlich noch da sind?

Gruß
PP
 
Hat es einen bestimmten Grund, dass du ein Array und keine String als Pfadvariable nutzt?

Er kann sich ja nicht selbst raussuchen was für rein Objekt-Typ NSSearchPathForDirectoriesInDomains zurückliefert. ;)
Dies ist nun mal ein Array.

Schreibt er da "NSString *path" davor, läuft das Programm eben nicht mehr.
 
Diese Pfadanzeige/-ermittlung funktioniert sowohl auf dem Simulator als auch auf dem Handy?
Jupp.

Hat es einen bestimmten Grund, dass du ein Array und keine String als Pfadvariable nutzt?
Ja, natürlich. Ich muss das nehmen, was mir die Funktion zurück gibt. Die Funktion kann, wenn man in mehreren Domains sucht, auch mehrere Pfade zurück liefern.

Meine erstellte Plist mit einigen Testdaten findet das Prog über den Bundle Pfad, und kann die Werte auch auslesen. Nur dauerhaft speichern ist nicht möglich. Liegt das daran, dass Xcode jedesmal eine neues "Projekt" anlegt, wenn ich die Software starte? Damit ändert sich ja auch jedes mal der Document Ordner. Wie kann ich also im Simulator testen, ob gespeicherte Daten nach dem beenden auch wirlich noch da sind?
Wenn Du in den „Documents“ Ordner speicherst, sollten die Daten auch erhalten bleiben, so lange du nicht das Programm vom Simulator löschst.

MacApple
 
Hi Leute und Danke für die vielen Infos.

Wie ja oben zu sehen ist benutze ich einen String als Pfadspeicher und das funktioniert auch problemlos. Liegt das daran, dass das iPhone/Mac eine einzelne Domain darstellt und nur ein Pfad zurückgegeben wird? Warum gibt es keine Fehlermeldung, wenn ich das Array in den String reinwerfe?

Pink_Panter
 
Jupp.
Wenn Du in den „Documents“ Ordner speicherst, sollten die Daten auch erhalten bleiben, so lange du nicht das Programm vom Simulator löschst.

Dieser Documents Ordner liegt aber innerhalb der Aktuell laufenden Anwendung. D.h., wenn ich den Simulator beende und neu starte, wird ein neuer Documents Ordner angelegt.Die Daten bleiben zwar im alten Documents Ordner, aber der ist ja dann nicht mehr in meinem aktuellen Ordner.
 
Dieser Documents Ordner liegt aber innerhalb der Aktuell laufenden Anwendung.
Nein, der liegt „neben“ der laufenden Anwendung.

D.h., wenn ich den Simulator beende und neu starte, wird ein neuer Documents Ordner angelegt.Die Daten bleiben zwar im alten Documents Ordner, aber der ist ja dann nicht mehr in meinem aktuellen Ordner.
Nein, es wird nur ein neuer Documents Ordner angelegt, wenn Du das Programm richtig vom Simulator löschst. Also genau so wie auf einem echten Device durch langes drauftappen bis es anfängt zu wackeln und dann das (x) antippen.

Es gibt aber eine kleine Falle, in die man eventuell tappen kann. Der Simulator unterstützt unter iOS 4.x auch das Multitasking, d.h. ein Klick auf den Home-Button beendet das App nicht unbedingt.

MacApple