Ist Swift inkompatibel mit Pre-ARC Objective-C?

8

Ich fange an, Swift-Dateien zu einem sehr großen, älteren Objective-C-Projekt hinzuzufügen, das ARC nicht verwendet.

Wenn ich das Projekt kompiliere, erhalte ich Warnungen für jede Eigenschaft, die im Header ProjectName-Swift.h bridge ausgegeben wird:

  • Kein 'assign', 'retain' oder 'copy' Attribut ist angegeben - 'assign' wird angenommen
  • Das Standardeigenschaftenattribut 'assign' ist nicht für Nicht-GC-Objekte geeignet

Es scheint, als ob Swift ARC-basierten Objective-C-Code ausgibt.

Ist dies eine Einschränkung / ein Fehler in dieser speziellen Version von Swift, oder ist Swift so konzipiert, dass sie nur mit ARC-Code funktioniert?

    
Bill 07.06.2014, 13:40
quelle

3 Antworten

10

Sie können ARC- und Nicht-ARC-Code mischen. Der gesamte von ARC kompilierte Code verwaltet seinen Speicher automatisch für den Benutzer. Sie sollten ARC für Ihr Projekt aktivieren und dann ARC für einzelne Dateien mit -fno-objc-arc deaktivieren oder ARC nur für Swift-Dateien mit -fobjc-arc aktivieren (dies ist möglicherweise nicht notwendig, da der Compiler es automatisch hinzufügen könnte). Swift-Code wird schließlich kompiliert, um dieselbe Objective-C-Laufzeit zu verwenden, und ARC-Aufrufe, die vom Compiler eingefügt werden, sind die gleichen wie in Objective C. Nach der Kompilierung verhalten sich ARC- und Nicht-ARC-Code gleich.

    
Leo Natan 07.06.2014, 14:15
quelle
0
  

Wenn ich das Projekt kompiliere, erhalte ich Warnungen für jede Eigenschaft, die im Header der ProjectName-Swift.h-Bridge ausgegeben wird

Ich konnte die Warnungen loswerden, nachdem ich alle meine Dateien in ARC umgewandelt hatte. (Nicht mit -fno-objc-arc )

    
Gomfucius 26.05.2015 18:50
quelle
0

Die Header-Datei, die Swift für Obj-C generiert, scheint davon auszugehen, dass ARC in Ihrem Obj-C-Code verwendet wird. Abhängig von Ihrer Xcode-Version und Ihren Build-Einstellungen ist möglicherweise eine Warnmeldung aktiviert, die Sie warnt, wenn eine Eigenschaft implizit eine assign -Eigenschaft ist. Dies ist nur in Nicht-ARC-Code der Fall, wie im ARC-Code. Eigenschaften sind implizit strong (das ist genau dasselbe wie retain in Nicht-ARC-Code). Wenn diese Warnung aktiviert ist, erhalten Sie diese Warnung jedes Mal, wenn Sie den generierten Header in eine .m-Datei importieren, die nicht ARC ist, und Swift kein Speicherattribut für diese Eigenschaft festgelegt hat.

Aber diese Warnung bedeutet nicht, dass der kompilierte Code später nicht korrekt funktionieren wird. Obwohl der Compiler glaubt, dass diese Eigenschaft nur assign ist, wird es sicher nicht assign sein, da Swift-Eigenschaften nicht einmal assign sein können, sie können strong sein oder weak (% co_de) % ist nicht dasselbe wie weak ! assign -properties werden weak , wenn das Objekt stirbt, nil -properties werden zu schwebenden Zeigern und zeigen immer noch auf die Adresse, wo das Objekt lebte. Das Schlimmste, was dies trotz der Warnung verursachen kann, ist ein falsches Ergebnis des statischen Code-Analysators, da der Analysator Sie auch warnen kann, wie diese assign -Eigenschaft Ihren Code brechen kann und der Analysator wiederum falsch ist, da die Eigenschaft simple nicht ist assign in der Realität.

Um das zu beheben, mussten wir uns nur noch darauf verlassen, dass eine Eigenschaft standardmäßig nichts ist und alle Eigenschaften immer korrekt als assign gekennzeichnet werden. Dies funktioniert auch in Nicht-ARC-Code ( strong und% co_de) % sind nur Synonyme für den Compiler, es behandelt beide genau gleich, so dass beide in Nicht-ARC-Code verwendet werden können). Das Seltsame ist oft, dass Swift genau das tut. Ich habe Tonnen von strong Eigenschaften in meinem generierten Header, aber anscheinend gibt es Situationen, in denen Swift es nicht tut (vielleicht ist das tatsächlich ein Swift Bug).

Eine einfache Lösung für dieses Problem besteht darin, die Warnung beim Importieren des generierten Headers einfach zu deaktivieren, was wie folgt geschehen kann:

%Vor%

Packen Sie das einfach in eine andere Header-Datei, z. retain und dann nur strong überall in deinen Code importieren.

Ich würde es nicht für das gesamte Projekt deaktivieren (zB in den Xcode-Build-Einstellungen), da diese Warnung normalerweise sehr aussagekräftig ist und schreckliche Bugs beim Mischen von ARC- und Nicht-ARC-Code verhindern kann. Sie haben wirklich das Speicherattribut, von dem Sie denken, dass es dieses hat, und daher wird Ihnen dringend geraten, sich niemals auf implizite Attribute zu verlassen und den Speicher immer explizit zu machen, wenn Sie ARC und Nicht-ARC mischen.

    
Mecki 08.03.2017 17:10
quelle