Statischen Array mit Klassenobjekten und direkter Zugriff

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Statischen Array mit Klassenobjekten und direkter Zugriff

    Hallo Welt ! ;)

    Ich bin neu in ObjectiveC und habe jetzt auch "Objective C und Cocoa" Buch durch. Leider blieb mir aber eine einfache Frage zu den Arrays unerklärt.
    Deshalb dachte ich ich frage mal die Spezialisten ^^ Konkret sind es zwei Fragen:


    1) Eigentlich will ich ein gaaanz einfaches Array namens units aus Klassenobjekten auf machen. Nichts mit Automatischen Verwaltungsfunktionen, in etwa einfach
    etwas in dieser Art:

    units unitArray[10000];
    unitArray[243].paramter1=43; ^^

    Blanko erzeugen, fixe Anzahl an Objekten, Zugriff dann direkt. So geht das aber leider nicht, zumindest habe ich nicht die Korrekte Codeimplementierung heraus
    gefunden. Meine Frage: Geht das doch irgendwie, so wie ich es aus Visual C++ kenne? ?(


    2) Als Notlösung habe ich jetzt die NSMutableArray Variante ausprobiert. Das geht, aber was ich komisch finde ist, das ich immer erst ein einzelnes Objekt
    haben muss das ich dann in den Array quetsche. Und wenn ich Zugreifen will geht das auch wieder nicht direkt sondern ich muss [unitArray objectAtIndex:x]
    mir immer ein Objekt herausziehen auf das ich dann wieder zugreifen kann. Das wäre mir jetzt so von mir aus auch recht über den zwischen Schritt,
    aber wie sieht es mit der Performance aus? Da wird nicht ein komplettes Objekt mit allen Variablen aus dem Pott gezogen? So wie ich es sehe wird da
    nur der Zeiger auf das Objekt gezogen. Das wäre dann wegen der Performance vertretbar, aber direkter geht es nicht oder? ?(


    Hier der Quellcode:

    Quellcode

    1. NSMutableArray *unitArray= [[NSMutableArray alloc] initWithCapacity:200]; // Anzahl ist nur geschätzt, ergibt kein Limit!
    2. Units *aUnit = [Units new]; // Einzelnes Objekt anlegen
    3. aUnit.age=99;
    4. [unitArray addObject:aUnit]; // Einzelnes Objekt in Objekt Array packen
    5. for( int i = 0; i < 10000; i++) // viele Objekte in den Array füllen
    6. {
    7. aUnit = [Units new];
    8. aUnit.age=99;
    9. [aUnit setAge:99]; // andere Schreibart
    10. [aUnit ageUp]; // Klassen methoden starten
    11. [unitArray addObject:aUnit];
    12. }
    13. // Objekt an Indexposition x holen und über IndexUnit zugänglich machen
    14. Units *indexUnit = [unitArray objectAtIndex:33];
    15. [indexUnit setAge:4];
    16. aUnit.age=99;
    Alles anzeigen



    Grüße und schon mal vielen Dank für jedwedes Feedback, :thumbsup:
    Rayjunx

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RayJunx ()

  • C-Arrays sind böse :) Dein Ansatz mit NSMutableArray ist der richtige. Über die Geschwindingkeit solltest Du Dir erst nach eingehenden Messungen (und wenn diese belegen, dass NSMutableArray zu langsam ist, was sehr unwahrscheinlich ist...) Gedanken machen:

    Donald Knuth schrieb:


    "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

    Ach ja, und bitte benutze Code-Tags.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Markus Müller ()

  • Ich sehe aufs erste keinen grund warum das in C nicht gehen sollte. Sofern der typ "units" vorher definiert ist kannst du auch ein unitArray[] drausmachen. Wirklich schön ist das natürlich nicht wenn du das direkt am stack machst, sodass du dir ab einer gewissen größe des type "units" was anderes überlegen solltest (malloc,...).

    Was meinst du denn mit "so geht das nicht" ? Gibts einen fehler beim kompilieren oder in runtime ?

    Der weg über arrays ist natürlich immer möglich aber wesentlich viel langsamer, weil du aus jeder noch so kleinen datenmenge erstmal ein objekt machen musst (mit seinen vorteilen aber auch nachteilen).

    Ein NSMutableData würde sich anbieten wenn du mit einfachen daten hantierst. Dort kann man direkt mit C an die bytes und trotzdem ist das ganze ein objekt.
  • RayJunx schrieb:

    2) Als Notlösung habe ich jetzt die NSMutableArray Variante ausprobiert. Das geht, aber was ich komisch finde ist, das ich immer erst ein einzelnes Objekt
    haben muss das ich dann in den Array quetsche. Und wenn ich Zugreifen will geht das auch wieder nicht direkt sondern ich muss [unitArray objectAtIndex:x]
    mir immer ein Objekt herausziehen auf das ich dann wieder zugreifen kann. Das wäre mir jetzt so von mir aus auch recht über den zwischen Schritt,
    aber wie sieht es mit der Performance aus? Da wird nicht ein komplettes Objekt mit allen Variablen aus dem Pott gezogen? So wie ich es sehe wird da
    nur der Zeiger auf das Objekt gezogen. Das wäre dann wegen der Performance vertretbar, aber direkter geht es nicht oder?


    Wo gehts denn direkter? Ein

    Quellcode

    1. [unitArray objectAtIndex:x]


    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]


    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.
    [self setSignature:null];
    [[self postCount] increment];
  • Und neuerdings gehen ja auch beide Schreibweisen (wie man das finden soll sei mal dahingestellt). Die Zeile zum Zugriff kann also seit dot notation und indexed subscripting genau so aussehen wie im OP.

    Was unterschiedlich bleibt ist die Erzeugung des Arrays - das muss man initialisieren. Und das ist ja auch ganz sinnvoll, weil nur der Programmierer wissen kann, wie die Objekte initialisiert werden sollen.
    Multigrad - 360°-Produktfotografie für den Mac
  • So hätte ich es gerne gemacht:

    Quellcode

    1. Units unitArray[1000]; // Array of interface Units is invalid, probably should be an array of pointers!

    Aber das geht offenbar nicht.

    Aber seis drum ich mache das jetzt alles mit NSMutableArray und greife zu mit dem "Units *indexUnit = [unitArray objectAtIndex:33];" drauf zu.


    erschien mir anfangs etwas zu umständlich, aber es funktioniert und ein flexibel erweiterbarer Array hat auch Vorteile.
    Irgendwann brauch ich die Funktionen die bereits integriert sind vielleicht also mach ich das jetzt so.
  • Mike schrieb:

    [

    Quellcode

    1. [unitArray objectAtIndex:x]


    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]


    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.


    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    Mike schrieb:

    [

    Quellcode

    1. [unitArray objectAtIndex:x]


    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]


    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.


    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Gruß

    Claus


    ich glaub die meinen hier die neue schreibweise bei NSArrays (eine sünde so einen müll einzuführen)
  • Thallius schrieb:

    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Da vertut man sich leicht. Natürlich ist ein indizierter Lookup schneller als ein dynamischer Dispatch, aber der vielbeschworene eine Befehl ist in der Realität eher Theorie. Faktor 1000 wirst du da nicht sehen. Abgesehen davon sieht man das Konstrukt nie isoliert. In einigen Situationen mag das einen relevanten Unterschied machen, in den meisten eher nicht. POITROAE.
    Multigrad - 360°-Produktfotografie für den Mac
  • mattik schrieb:

    Thallius schrieb:

    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Da vertut man sich leicht. Natürlich ist ein indizierter Lookup schneller als ein dynamischer Dispatch, aber der vielbeschworene eine Befehl ist in der Realität eher Theorie. Faktor 1000 wirst du da nicht sehen. Abgesehen davon sieht man das Konstrukt nie isoliert. In einigen Situationen mag das einen relevanten Unterschied machen, in den meisten eher nicht. POITROAE.


    Es ging mir nicht um POITROAE sondern darum klar zu machen, dass es eben nicht das gleiche ist. Es sind zwei vollkommen verschiedene Dinge die auch zwei vollkommen unterschiedliche Einsatzzwecke haben.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • RayJunx schrieb:

    So hätte ich es gerne gemacht:

    Quellcode

    1. Units unitArray[1000]; // Array of interface Units is invalid, probably should be an array of pointers!

    Aber das geht offenbar nicht.

    Aber seis drum ich mache das jetzt alles mit NSMutableArray und greife zu mit dem "Units *indexUnit = [unitArray objectAtIndex:33];" drauf zu.


    erschien mir anfangs etwas zu umständlich, aber es funktioniert und ein flexibel erweiterbarer Array hat auch Vorteile.
    Irgendwann brauch ich die Funktionen die bereits integriert sind vielleicht also mach ich das jetzt so.

    Es geht, wenn du ein Array von Objektzeigern draus machst. Dann musst die Objekte aber auch wieder erzeugen. Irgendwie versuchst du etwas zu machen, was du zwar kennst (Vorteil für dich) aber nicht zur Sprache passt (Nachteil für das System). Da das System immerRecht hat, fliegst du damit auf die Schnauze. Lernerfolg: Nicht machen.

    Nimm ein NSArray. Gewöhn dich daran, Objekte zu nehmen. Alles andere sind Windmühlen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Thallius schrieb:

    Mike schrieb:

    [

    Quellcode

    1. [unitArray objectAtIndex:x]


    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]


    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.


    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Gruß

    Claus

    Zu welchem Problem ist das denn die Lösung? Zu dem Problem Arrayzugriff? Ein solches Problem existiert nicht. Der Zugriff ist nur ein Teil eines größeren Problems. Macht er 1 % der Gesamtlösung aus, so kann eine Optimierung nie mehr als 1 % bringen.

    Da dürfte es in der Regel erfolgreicher sein, sich solchen Fragen erst gar nicht zu widmen, sondern eine algorithmische Optimierung zu suchen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Thallius schrieb:

    Mike schrieb:


    Quellcode

    1. [unitArray objectAtIndex:x]

    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]

    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.

    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Claus, ich denke, du verwechselst da was.
    Meinem Dafürhalten meint Mike mit beiden Beispielen reinen Objective-C Code.
    Da wird unitArray[x] intern von wem auch immer (Runtime?) nach [unitArray objectAtIndex:x] aufgelöst und ist damit eher um den Faktor 0 schneller.
    Der OP sprach von reinen C-Arrays, Mike verglich zwei Schreibweisen von NSArrays. Du vergleichst als Einziger reine C-Arrays mit NSArrays.

    Die Zugriffszeiten, die du dir bei einem reinen C-Array auf Pointer sparst, hast du an anderer Stelle durch den Mehraufwand der Speicherverwaltung.
    In dem Kontext "Zugriff auf Objektinstanzen in einem Array" sämtliches Augenmerk auf den Teilaspekt "Zugriff in einem Array" zu reduzieren halte ich für fachlich falsch und daher die Prognosen bezüglich der Zeitersparnis für nicht aussagekräftig.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Lucas de Vil schrieb:

    Thallius schrieb:

    Mike schrieb:


    Quellcode

    1. [unitArray objectAtIndex:x]

    ist quasi das Selbe wie ein

    Quellcode

    1. unitArray[x]

    es ist halt "nur lesbarer". Es sind eigentlich, wie sag ichs nur, andere Darstellungsarten IMO.

    Naja funktionell mag das stimmen aber performancemäßig liegen dazwischen Welten. Im ersten fall werden Unmengen an maschinencode durchlaufen, während im zweiten fall genau ein proessorbefehl gebraucht wird. Die zweite Lösung dürfte locker um den faktor 100 wenn nicht gar 1000 schneller sein.

    Claus, ich denke, du verwechselst da was.
    Meinem Dafürhalten meint Mike mit beiden Beispielen reinen Objective-C Code.
    Da wird unitArray[x] intern von wem auch immer (Runtime?) nach [unitArray objectAtIndex:x] aufgelöst und ist damit eher um den Faktor 0 schneller.
    Der OP sprach von reinen C-Arrays, Mike verglich zwei Schreibweisen von NSArrays. Du vergleichst als Einziger reine C-Arrays mit NSArrays.

    Die Zugriffszeiten, die du dir bei einem reinen C-Array auf Pointer sparst, hast du an anderer Stelle durch den Mehraufwand der Speicherverwaltung.
    In dem Kontext "Zugriff auf Objektinstanzen in einem Array" sämtliches Augenmerk auf den Teilaspekt "Zugriff in einem Array" zu reduzieren halte ich für fachlich falsch und daher die Prognosen bezüglich der Zeitersparnis für nicht aussagekräftig.

    Es wird vom Compiler zu -objectAtIndexedSubscript: übersetzt.
    clang.llvm.org/docs/ObjectiveC…#array-style-subscripting
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    Lucas de Vil schrieb:


    Da wird unitArray[x] intern von wem auch immer (Runtime?) nach [unitArray objectAtIndex:x] aufgelöst und ist damit eher um den Faktor 0 schneller.

    Es wird vom Compiler zu -objectAtIndexedSubscript: übersetzt.
    clang.llvm.org/docs/ObjectiveC…#array-style-subscripting

    Danke für die Erleuchtung! :-]
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • *lol* so genau wollte ich es eigentlich garnicht ;)
    Ihr habt mich schon überzeugt, in meinem Fall sind alle anderen Dinge die ich vorhabe tausend mal mehr von Bedeutung als die Verwaltung der Objekte.
    Vielleicht kommt ich aber mal auf den Punkt zurück wenn ich was Programmiere bei dem es primär auf die Zugriffszeiten auf verschiedene Objekte angeht.
    Aber ich Danke Euch, Ihr habt mich überzeugt ^^