2016-07-19 8 views
2

Ich versuche, eine einfache Abfrage auf meine erste Realm-Datenbank zu tun. Beim Versuch, auf die Attribute eines von meiner Abfragemethode zurückgegebenen Objekts zuzugreifen, erhalte ich einen Fehler. Ich habe zwei Fragen:
1. Was ist die Bedeutung dieses Fehlers? Ich habe Probleme, es zu verstehen ...
2. Mache ich die Abfrage den richtigen Weg? Wenn nicht, was mache ich falsch?Fehler in der Realm-Abfrage um (Wrapper verwaltet-zu-native) Realms.NativeTable.get_string

Das Fehlerprotokoll:

[mono-rt] Stacktrace: 

[mono-rt] at <unknown> <0xffffffff> 

[mono-rt] at (wrapper managed-to-native) Realms.NativeTable.get_string >(Realms.TableHandle,intptr,intptr,intptr,intptr,bool&) <0x00057> 

[mono-rt] at Realms.RealmObject.GetStringValue (string) <IL 0x0009d, >0x00323> 

[mono-rt] at EasyVending.RCreditCard.get_holderName() <IL 0x0000e, 0x0006f> 

[mono-rt] at EasyVending.RealmManager.getCreditCard() [0x0001c] in /Users/Bernardo/Projects/EasyVending/EasyVending/DataBase/RealmManager.cs:75 

[mono-rt] at EasyVending.Android.CreditCartManagement.OnCreate (Android.OS.Bundle) [0x00111] in /Users/Bernardo/Projects/EasyVending/EasyVending.Android/Activities/CreditCartManagement.cs:89 

[mono-rt] at Android.Support.V4.App.FragmentActivity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) <IL 0x00013, 0x000ff> 

[mono-rt] at (wrapper dynamic-method) object.13add723-97a5-4397-9c8a-e6fc23d98c3c (intptr,intptr,intptr) <IL 0x00017, 0x00043> 

[mono-rt] at (wrapper native-to-managed) object.13add723-97a5-4397-9c8a-e6fc23d98c3c (intptr,intptr,intptr) <IL 0x0001f, 0x00097> 

[mono-rt] Attempting native Android stacktrace: 

[mono-rt] at ???+1 [0xbe903ac0] 

[mono-rt] at ???+1 [0x98f50ffc] 

================================================================= 

Got a SIGSEGV while executing native code. This usually indicates 
[mono-rt] a fatal error in the mono runtime or one of the native libraries 
[mono-rt] used by your application. 
[mono-rt] 

[libc] Fatal signal 11 (SIGSEGV), code 1, fault addr 0x97b77168 in tid 9849 (vending_android) 

=================================== ==

public class RCreditCard : RealmObject { 
    public string holderName { get; set; } 
    public string bandeira { get; set; } 
    public string digitos { get; set; } 
    public string token { get; set; } 
} 

public class RealmManager { 
    private string databaseName { 
     get { 
      return "PayBluDatabase.db"; 
     } 
    } 
    private string androidPath { 
     get { 
      return Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), databaseName); 
     } 
    } 

    public Realm getRealm() { 
     return Realm.GetInstance(androidPath); 
    } 

    public void closeRealm(Realm realm) { 
     realm.Close(); 
    } 

    public Transaction insertCreditCard(EasyVending.CreditCard creditCard) { 
     var realm = getRealm(); 
     using(var transaction = realm.BeginWrite()) { 
      var insertedCreditCard = realm.CreateObject<RCreditCard>(); 

      insertedCreditCard.holderName = creditCard.HolderName; 
      insertedCreditCard.bandeira = creditCard.CreditCardBrand; 
      insertedCreditCard.digitos = creditCard.MaskedCreditCardNumber; 
      insertedCreditCard.token = creditCard.InstantBuyKey; 

      transaction.Commit(); 
      closeRealm(realm); 
      return transaction; 
     } 
    } 

    public Transaction removeCreditCard() { 
     var realm = getRealm(); 
     using(var transaction = realm.BeginWrite()) { 
      realm.RemoveAll<RCreditCard>(); 
      transaction.Commit(); 
      closeRealm(realm); 
      return transaction; 
     } 
    } 

    public CreditCard getCreditCard() { 
     var realm = getRealm(); 
     var rCreditCard = realm.All<RCreditCard>().First(); 
     closeRealm(realm); 
     var creditCard = new CreditCard() { 
      CreditCardBrand = rCreditCard.bandeira, 
      MaskedCreditCardNumber = rCreditCard.digitos, 
      HolderName = rCreditCard.holderName 
     }; 
     return creditCard; 
    } 

    public bool hasCreditCard() { 
     bool answer = false; 
     var realm = getRealm(); 
     if(realm.All<RCreditCard>().Count() > 0) { 
      answer = true; 
     } 
     closeRealm(realm); 
     return answer; 
    } 
} 

der Fehler tritt auf, wenn ich jedes Attribut des RCreditCard Objekt durch meine Abfrage zurückgegeben zuzugreifen versuchen:

CreditCardBrand = rCreditCard.bandeira, 

von

var rCreditCard = realm.All<RCreditCard>().First(); 

Bitte lassen Sie mich wissen, wenn die Frage nicht klar genug war.

Antwort

1

Das Problem ist, dass Sie den Bereich schließen, bevor Sie versuchen, die Eigenschaften unter rCreditCard in getCreditCard() zu lesen. Eigenschaften in Realm-Objekten sind Nullkopie, sie greifen direkt auf die Datenbank zu, sobald das Realm geschlossen wird, wird das Objekt ungültig. Wir sollten besser mit dieser Situation umgehen, es ist im Moment nicht klar. Danke, dass Sie uns darauf hingewiesen haben!

Im Allgemeinen möchten Sie den Bereich wahrscheinlich nicht so oft öffnen und schließen wie Sie, es sei denn, diese Aufrufe finden in verschiedenen Threads statt. Wenn Sie darauf bestehen, sollten Sie Realm.Close() Aufrufe außerhalb der Transaktion using Bereiche bewegen. Wie jetzt, wenn etwas während der Transaktion ausgelöst wird, wird es zurückgerollt, aber Ihr Bereich wird nicht wie erwartet geschlossen.

Schließlich sollte eine "normale" Klasse, die Ihre RealmObject Klasse widerspiegelt, in der Regel nicht notwendig sein. Natürlich kann es Gründe geben, warum es in Ihrem Fall nicht so offensichtlich ist. Normalerweise würden Sie die Klassen RealmObject direkt verwenden.

+0

Das funktionierte tun können! Vielen Dank! Ich wusste nicht, dass das Objekt durch Schließen des Realms ungültig wird. Danke für die Erklärung! Es gibt tatsächlich einen Grund, warum ich eine normale Klasse verwende, die mein Realm-Objekt spiegelt, aber sie haben einige Unterschiede. Zuletzt noch eine Frage: Was müsste ich tun, wenn ich beim Methodenaufruf eine rCreditCard zurückgeben wollte? Ich sollte es zurückgeben und ein offenes Reich verlassen? –

+0

Ja - lassen Sie den Realm offen, wahrscheinlich haben Sie ihn als Eigenschaft in Ihrer Modellklasse. –

1

Was sagte Kristian ;-)

Nur um zu klären, ob Sie Muss geöffnet und das Reich häufig in der Nähe, die Sie gerade mit

using (var realm = getRealm()) { 
// your update and read logic 
}