2016-07-19 1 views
2

Я пытаюсь сделать простой запрос в своей первой базе данных Realm. Я получаю сообщение об ошибке при попытке получить доступ к атрибутам объекта, возвращаемого моим методом запросов. У меня есть два вопроса:
1. В чем смысл этой ошибки? У меня возникли проблемы, чтобы понять это ...
2. Правильно ли я делаю запрос? Если нет, что я делаю неправильно?Ошибка в Realm Query at (wrapper managed-to-native) Realms.NativeTable.get_string

Журнал ошибок:

[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; 
    } 
} 

ошибка возникает при попытке получить доступ к любому атрибуту объекта RCreditCard возвращенного мой запрос:

CreditCardBrand = rCreditCard.bandeira, 

из

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

Пожалуйста, дайте мне знать, если вопрос недостаточно ясен.

ответ

1

Проблема в том, что вы закрываете область, прежде чем пытаться прочитать свойства на rCreditCard в getCreditCard(). Свойства объектов Realm имеют нулевую копию, они напрямую обращаются к базе данных, поэтому, как только вы закрываете область, объект становится недействительным. Мы должны лучше справляться с этой ситуацией, пока неясно. Спасибо, что указали это нам!

В общем, вы, вероятно, не хотите открывать и закрывать царство так часто, как вы, если только эти вызовы не происходят на разных потоках. Если вы настаиваете на этом, вы должны переместить Realm.Close() звонки за пределами транзакции using областей. Как и сейчас, если что-то бросает во время транзакции, оно будет отменено, но ваше царство не будет закрыто, как вы могли бы ожидать.

Наконец, наличие «нормального» класса, который отражает ваш класс RealmObject, обычно не требуется. Конечно, могут быть причины, почему это в вашем случае, которые здесь не очевидны. Как правило, вы должны использовать классы RealmObject напрямую.

+0

Это сработало! Благодаря! Я не знал, что закрывая область, объект становится недействительным. Спасибо за объяснение! Существует действительно причина, по которой я использую обычный класс, который отражает мой объект realm, но у них есть некоторые отличия. Прежде всего, еще один вопрос: что мне делать, если я захочу вернуть rCreditCard при вызове метода? Я должен вернуть его и оставить открытое царство? –

+0

Да - оставьте область открытой, вероятно, она будет иметь свойство в вашем классе модели. –

1

Что Kristian сказал ;-)

Просто для уточнения, если вы сусло открывать и закрывать Realm часто, вы можете просто сделать это с

using (var realm = getRealm()) { 
// your update and read logic 
} 
Смежные вопросы