Frage

Hallo Ich brauche eine NSObject an einer bestimmten Stelle zu initialisieren, dass ich (über einen void * Zeiger, zum Beispiel) angeben. Für ein wenig Kontext, schreibe ich eine sqlite3 Aggregatfunktion. Um temporäre Ergebnisse aus dieser Funktion zu halten, muss ich eine sqlite3_aggregate_context Funktion aufrufen, die für mich einen Speicherblock zuweist. Ich mag eine NSDecimalNumber an diesem Ort speichern.

Bisher habe ich versucht, zwei Ansätze:

1) allocWithZone, indem Sie:

void *location = sqlite3_aggregate_context(...); //returns a block of allocated memory of a certain size

NSDecimalNumber *num = [[NSDecimalNumber allocWithZone:NSZoneFromPointer(location)] initWithInt:0];

Das funktioniert nicht, weil NSZoneFromPointer gibt nil zurück. Docs sagen, dass die Argumente für diese Funktion ein zuvor zugewiesenen Zeiger sein muss, was es ist. Ich weiß nicht, ob dieses Mittel mit NSZoneMalloc / calloc zugeordnet.

2)

id location = sqlite3_aggregate_function(...);

location = [[NSDecimalNumber alloc] init];

, aber das verursacht eine Art Endlosschleife, wenn Sie die Speicher zu befreien ... nicht sicher, was das Geschäft ist. Ein Screenshot hier: http://dl.dropbox.com/u/3002073/Public%20Sync /sqlitefunctionissue.png

wird Irgendwelche Vorschläge sehr geschätzt werden!

War es hilfreich?

Lösung

Sie können nicht wirklich zuverlässig bestimmen, wo ein Objekt wird im Speicher erstellt werden. Die NSZoneFromPointer nicht für Sie, weil die sqlite3-API ist nicht Zonen mit ihren Ressourcen zuzuweisen.

Wenn Sie in der Lage sein wollen, einen bestimmten Ort zu übergeben, sollten Sie tun, um einen Zeiger auf den Gegenstand (so dass Sie einen Zeiger auf einen Zeiger im Grunde zu speichern). Sie können dann diese Informationen von Ihrer Aggregatfunktion gelesen und es entsprechend aktualisieren. So stellen Sie sicher, dass Sie nicht einfach lassen Sie Ihre Objekt am Ende des Anrufs befreit werden, ohne darauf achten, dass sie lösen (oder Sie ein Leck haben).

So zum Beispiel könnte man so etwas tun:

NSDecimalNumber** numberLocation = sqlite3_aggregate_context(...);
*numberLocation = [[NSDecimalNumber alloc] initWithDouble:25.0];

Sie jetzt einen Verweis auf das Objekt haben in Ihrem speziellen Speicherbereich abgelegt und kann es jederzeit zugreifen:

NSDecimalNumber* storedNumber = *numberLocation;
NSDecimalNumber* computedNumber = [[NSDecimalNumber alloc] initWithDouble:[storedNumber doubleValue] * someComputation];
[storedNumber autorelease];
*numberLocation = computedNumber;

Auf der anderen Seite, ich stimme mit Mark; vielleicht diese unveränderliche Klasse ist nicht die beste Lösung für Ihr Problem?

Andere Tipps

Ihre erste Version wird einfach nicht funktionieren. NSZoneFromPointer funktioniert nur, wenn ein Zeiger aus einer Zone zugeordnet geben. Es wird verwendet, so dass Sie ein Objekt aus der gleichen Zone wie ein anderes Objekt zuordnen kann.

Die zweite Version zu arbeiten soll, obwohl es schwierig ist, ohne mehr Kontext zu erzählen. Was sind vorbei Sie als die Größe des Speichers sqlite3_aggregate_context zuzuweisen? Und wie zu befreien Sie, dass der Speicher, wenn Sie fertig sind?

Die zweite Version funktioniert nicht, weil der „id“ Typ tatsächlich ein Zeiger ist, so dass Sie es auf dem Speicher zurück von sqlite3_aggregate_context () sind zeigen, dann ist es an dem von alloc / init zurückgeführtem Speicher zeigt. Man braucht wirklich einen Zeiger-zu-Zeiger zu speichern, dass die Art und Weise Sie wollen arbeiten.

NSDecimalNumber ist eine unveränderliche Klasse, so -init fordert sie auf (im Gegensatz zu -initWithDecimal Gegensatz :) wird nur Ihnen einige Standardwerte zu erhalten. Welche Art von Code verwenden Sie die NSNumber mit neuen Werten, wie die Funktion Fortschritte zu ersetzen?

Mehr zu dem Punkt, warum Gebrauch NSDecimalNumber überhaupt, wie auf eine C ganze Zahl im Gegensatz oder doppelt, oder was auch immer?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top