HINWEIS: Dies war auf einen Fehler in einigen XCode-Betaversionen zurückzuführen, der längst behoben ist. Diese Frage und Antwort wird Ihnen wahrscheinlich nicht helfen, wenn Sie Probleme mit ARC haben.
Ich bin dabei, mein Projekt von der manuellen Referenzzählung auf ARC umzustellen, und bin dabei auf ein Problem gestoßen: Wie kann ich sicherstellen, dass ein benutzerdefinierter Setter für eine Retain-Eigenschaft tatsächlich beibehalten wird?
Unter myClass.h
habe ich eine Eigenschaft deklariert: @property (retain) NSDate *date
. Es spielt keine Rolle, ob ich manuell eine __strong
ivar oder lassen Sie es automatisch generieren.
Bei der Umsetzung habe ich natürlich @synthesize date
und implementierte einen benutzerdefinierten Setter (oder einfach das Xcode-Demoprojekt herunterladen ) :
- (void)setDate:(NSDate *)newDate
{
if (allowedToSetNewDate)
{
date = newDate;
}
}
Dies scheint das Datum nicht beizubehalten und führt dazu, dass ich message sent to deallocated instance
wenn newName (auto-) freigegeben wird, woher er kam, wenn versucht wird, auf myClass.date
später (vorausgesetzt, Zombie ist aktiviert; andernfalls stürzt es einfach ab).
Ändern des Setters zur Verwendung von date = [newDate copy]
umgeht den Fehler, ist aber nicht wirklich das, was ich will. Das Löschen des benutzerdefinierten Setters funktioniert auch, ist aber offensichtlich nicht erwünscht.
Was übersehe ich hier? Wie kann ich sicherstellen, dass ein benutzerdefinierter Setter für eine Retain-Eigenschaft tatsächlich in einer ARC-Umgebung beibehält? Dies scheint so eine grundlegende und gemeinsame Aufgabe, die ich denke, ich bin etwas sehr offensichtlich übersehen.
(HINWEIS: Dies fällt nicht unter die Bedingungen eines Apple NDA, da ARC als Teil von LLVM öffentlich freigegeben ist)
EDIT: Ich habe ein kleines Xcode-Projekt erstellt, um das Problem zu demonstrieren und es auf github hochgeladen. Fühlen Sie sich frei zu Herunterladen und herumspielen. Ich bin mit meinem Verstand am Ende (obwohl mein Verstand heute zugegebenermaßen nicht der beste ist).
EDIT: Für dieses Beispielprojekt ist dieses Problem gelöst (siehe akzeptierte Antwort). Leider besteht das Problem in dem größeren Projekt, das ich nicht freigeben darf, weiterhin. Als Workaround habe ich ein Duplikat hinzugefügt strong
Eigenschaften mit synthetischen Setzern (ivars funktionieren nicht). Der neue benutzerdefinierte Setter sieht nun wie folgt aus:
- (void)setDate:(NSDate *)newDate
{
if (allowedToSetNewDate)
{
self.date_arcretain = newDate; //this property is only there as a workaround. ARC properly retains it, but only if the setter is synthesized
date = newDate;
}
}