BOOLs unter Mac Catalyst: Eine Frage der Architektur

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

  • BOOLs unter Mac Catalyst: Eine Frage der Architektur

    Moin!

    Vielleicht kann ich jemandem das Suchen ersparen: Ich habe gerade einen Bug meiner App unter Mac Catalyst gefixt, der mich ganz schön in's Grübeln brachte - in diesem Forumsbereich, weil es um die macOS-Seite geht:

    Situation:
    Ich zeige in einer UITableView eine Reihe (18) von UISwitches an, die Export-Optionen der App repräsentieren und im Core-Data-Modell bitweise in einem Int32 gespeichert werden. Zum Konfigurieren der UITableViewCell nutze ich den folgenden Code, um jeweils das x. Bit abzufragen und den Schalter entsprechend zu setzen:

    Quellcode

    1. int32_t exportOptions = self.store.exportAttributes;
    2. optionSwitch.on = (exportOptions & (0x00000001 << indexPath.row));
    Problem:

    Unter iOS funktioniert der ViewController wie gewünscht. Die App unterstützt Mac Catalyst und unter macOS ergibt sich ein (zunächst) merkwürdiges Bild: Während die oberen Schalter ein konsistentes Verhalten zeigen, werden die unteren / späteren scheinbar willkürlich gesetzt und nach Umschalten auch wieder zurück gesetzt, wenn in der Ansicht geblättert (und die Zelle damit neu konfiguriert) wird. Sehr offensichtlich wird das Problem, da die Core-Data-Basis via iCloud synchronisiert wird und man so direkt die unterschiedlichen Schalterstellungen zwischen iOS und macOS erkennen kann.

    Lösung:
    Das Problem liegt in der 2. Code-Zeile: Die Zuweisung nach der bitweisen AND-Operation ergibt unter iOS (besser: auf Apple-Prozessoren) implizit ein natives bool und die Zuweisung zum UISwitch-Property ist sauber. Auf einem Intel-Mac ist ein BOOL aber ein signed char, die implizite Konvertierung ergibt ein anderes Ergebnis. Um die Schalter sauber zu setzen, müsste man das Ergebnis der AND-Operation entweder gegen Null prüfen oder mit zweifachem Negieren ein bool erzwingen. Den entscheidenen Tipp fand ich hier in der Apple-Dokumentation. Der folgende Code funktioniert nun auf beiden Plattformen:

    Quellcode

    1. int32_t exportOptions = self.store.exportAttributes;
    2. optionSwitch.on = !!(exportOptions & (0x00000001 << indexPath.row));
    Vielleicht hilft es ja jemandem, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von MyMattes ()

  • Im Prinzip macht es der MAC richtig auch wenn mich sowas ebenfalls nervt da ein nicht 0 int genauso ein bool false darstellt in meinen Augen.

    Ich würde in diesem Fall aber tatsächlich eine andere Schreibweise wählen da ich das doppelte Ausführungszeichen tatsächlich nicht schön und auch irritierend finde

    Quellcode

    1. int32_t exportOptions = self.store.exportAttributes;
    2. optionSwitch.on = exportOptions & (0x00000001 << indexPath.row)) != 0 ? true : false
    finde ich leserlicher und leichter verständlich

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

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

    Ich würde in diesem Fall aber tatsächlich eine andere Schreibweise wählen da ich das doppelte Ausführungszeichen tatsächlich nicht schön und auch irritierend finde
    Ich gebe zu, dass ich zuerst auch einen Vergleich nutzte:

    Quellcode

    1. int32_t exportOptions = self.store.exportAttributes;
    2. optionSwitch.on = ((exportOptions & (0x00000001 << indexPath.row)) != 0);
    Letztlich fand ich das doppelte Negieren aber einen ganz netten Trick ... im Sinne der Lesbarkeit gebe ich Dir recht, daher hat der Original-Code auch einen entsprechenden Kommentar :)

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Nur der Vollständigkeit halber - ich bin eben wieder auf den selber Effekt hereingefallen: Das gleiche gilt (natürlich) auch zwischen M1- und Intel-Macs. Besonders ärgert mich, dass ich den Vergleich wieder unsauber codiert hatte (und so auf der Intel-Testmaschine Key-Modifier nicht mehr sauber erkannt wurden).

    Ich werde alt, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Und noch einer aus dieser Ecke:

    Quellcode

    1. NSInteger i = ...;
    2. BOOL flag = (i % 2);
    Funktioniert mit Monterey auf einem M1 und Intel Mac ... in einer VMware Fusion VM nicht, dort muss man explizit auf Ungleichheit mit Null vergleichen, um den gewünschte Effekt zu haben. Bescherte mir eine Endlosschleife im späteren Kontext.

    Ob ich das noch lerne?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.