iOS « Bernhard Krenz

Tag: iOS

Objective-C weak-Eigenschaft aus Swift

Mit der aktuellen Swift-Version scheint es nicht möglich zu sein, einer weak-Eigenschaft einer Objective-C-Klasse einen Wert zuzuweisen. Auch mit einem manuellen setter ist die Variable immer nil.

Dies betrifft vor allem den Fall, in dem in einem Swift-Projekt eine Objective-C Bibliothek genutzt wird, die zum Beispiel ein weak delegate besetzt.

@property (weak) id<Protocol> dataSource;

Die einzige Lösung bestand darin, die weak-Eigenschaft in eine strong-Eigenschaft zu ändern. Ich hoffe, dass Apple dafür einen Fix liefert.


if (![nil isEqualToString:nil]) { }

Das folgende Verhalten entspricht der Apple’s Objective-C 2.0 Dokumentation, ist aber möglicherweise nicht jedermann bekannt.

Bei einem Vergleich zweiter Strings in iOS mit isEqualToString, wird das „do something“ im folgenden Codeschnipsel auch ausgeführt, wenn beide Argumente nil sind, obwohl diese auf den ersten Blick gleich erscheinen.

if (![string1 isEqualToString:string2])
{
 // do something
}

Das liegt daran, dass eine Methode zu nil immer 0 zurückgibt und als false interpretiert wird. Die if-Bedingung ist damit erfüllt.

Die korrekt Art und Weise das obere Beispiel umzusetzen, wäre also:

if (![string1 isEqualToString:string2] && (string1 != nil || string2 != nil))
{
  // do something
}

Existiert eine Konstante?

Wer regelmäßig mit iOS arbeitet wird schnell einmal mit dem Problem konfrontiert, dass eine zu verwendende System-Konstante nur in einer neueren iOS-Version verfügbar ist.

Hier stellt sich die Frage, wie zu prüfen ist, ob die Konstante in der iOS-Version des Nutzers überhaupt zur Verfügung steht, um durch eine geeignete Weiche Abstürze zu vermeiden.

Das Ganze zeige ich am Beispiel einer Observer-Konstante des MPMoviePlayerControllers zum Abspielen von Videos, welche einem die Möglichkeit bietet, ein Video erst dann einzublenden, wenn das erste Frame zur Verfügung steht. Denn nur so kann man ein Flickern am Anfang des Videos vermeiden:

if (&MPMoviePlayerReadyForDisplayDidChangeNotification != NULL) // check if constant exists
{
	// >= iOS 6.0, use readyForDisplay property
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoIsVisibleChanged:) name:MPMoviePlayerReadyForDisplayDidChangeNotification object:nil];
}
else
{
	// < iOS 6.0, use playbackState property
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoStateChanged:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
}

Copyright © 2012-2019 Bernhard Krenz Alle Rechte vorbehalten.