such realmswift primary example data ios swift realm

ios - realmswift - realm swift example



El objeto Realm ha sido eliminado o invalidado (7)

Acabo de colocar el método breakpoint inside:

// Realm/RLMUtil.mm:193 static NSException *RLMException(NSString *reason, NSDictionary *additionalUserInfo) { // ... }

Y en el panel izquierdo puede verificar el seguimiento de la pila, aquí puede encontrar dónde arroja el error.

Cuando inicio mi aplicación, realizo una llamada API para ver si hay nuevos datos disponibles. Los datos se almacenan en mi base de datos de Realm local, y parte de ellos se muestran en el controlador de vista de tabla inicial.

Una vez que finaliza la llamada a la API, compruebo si se cumplen algunas condiciones que me exigen eliminar un montón de los datos anteriores de la base de datos y luego crear nuevos objetos. Sin embargo, cuando elimino los datos anteriores, mi aplicación se bloquea con la siguiente excepción:

2015-08-06 11:56:32.057 MSUapp[19754:172864] *** Terminating app due to uncaught exception ''RLMException'', reason: ''Object has been deleted or invalidated.'' *** First throw call stack: ( 0 CoreFoundation 0x000000010660cc65 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001083bdbb7 objc_exception_throw + 45 2 Realm 0x0000000105b78e95 _ZL17RLMVerifyAttachedP13RLMObjectBase + 85 3 Realm 0x0000000105b7878d _ZL10RLMGetLinkP13RLMObjectBasemP8NSString + 29 4 Realm 0x0000000105b7c23e ___ZL17RLMAccessorGetterP11RLMProperty15RLMAccessorCodeP8NSString_block_invoke_12 + 46 5 MSUapp 0x0000000105764867 _TFFC6MSUapp29FavoriteLeaguesViewController18generateLeagueListFS0_FT_T_U_FTCS_6LeagueS1__Sb + 39 6 MSUapp 0x00000001057648eb _TTRXFo_oC6MSUapp6LeagueoS0__dSb_XFo_iS0_iS0__dSb_ + 27 7 libswiftCore.dylib 0x0000000108674ae2 _TFSs14_insertionSortUSs21MutableCollectionType_USs13GeneratorType__Ss22BidirectionalIndexType_Ss18_SignedIntegerType_Ss33_BuiltinIntegerLiteralConvertible____FTRQ_GVSs5RangeQQ_5Index_RFTQQQ_9Generator7ElementS7__Sb_T_ + 1570 8 libswiftCore.dylib 0x0000000108676682 _TFSs14_introSortImplUSs21MutableCollectionType_USs13GeneratorType__Ss21RandomAccessIndexType_Ss18_SignedIntegerType_Ss33_BuiltinIntegerLiteralConvertible_Ss16SignedNumberType_S3_____FTRQ_GVSs5RangeQQ_5Index_RFTQQQ_9Generator7ElementS8__SbSi_T_ + 1250 9 libswiftCore.dylib 0x0000000108676172 _TFSs10_introSortUSs21MutableCollectionType_USs13GeneratorType__Ss21RandomAccessIndexType_Ss18_SignedIntegerType_Ss33_BuiltinIntegerLiteralConvertible_Ss16SignedNumberType_S3_____FTRQ_GVSs5RangeQQ_5Index_FTQQQ_9Generator7ElementS8__Sb_T_ + 1058 10 libswiftCore.dylib 0x00000001085ec947 _TFSs4sortUSs21MutableCollectionType_USs13GeneratorType__Ss21RandomAccessIndexType_Ss18_SignedIntegerType_Ss33_BuiltinIntegerLiteralConvertible_Ss16SignedNumberType_S3_____FTRQ_FTQQQ_9Generator7ElementS6__Sb_T_ + 471 11 libswiftCore.dylib 0x00000001086a8d9e _TPA__TFFSa4sortU__FRGSaQ__FFTQ_Q__SbT_U_FRGVSs26UnsafeMutableBufferPointerQ__T_ + 222 12 libswiftCore.dylib 0x00000001086a8e18 _TPA__TTRG0_R_XFo_lGVSs26UnsafeMutableBufferPointerq___dT__XFo_lGS_q___iT__42 + 56 13 libswiftCore.dylib 0x00000001085f7fda _TFSa30withUnsafeMutableBufferPointerU__fRGSaQ__U__FFRGVSs26UnsafeMutableBufferPointerQd___Q_Q_ + 522 14 libswiftCore.dylib 0x00000001085f7db4 _TFSa4sortU__fRGSaQ__FFTQ_Q__SbT_ + 132 15 MSUapp 0x0000000105761709 _TFC6MSUapp29FavoriteLeaguesViewController18generateLeagueListfS0_FT_T_ + 1097 16 MSUapp 0x000000010576354b _TFC6MSUapp29FavoriteLeaguesViewController27numberOfSectionsInTableViewfS0_FCSo11UITableViewSi + 59 17 MSUapp 0x00000001057635fa _TToFC6MSUapp29FavoriteLeaguesViewController27numberOfSectionsInTableViewfS0_FCSo11UITableViewSi + 58 18 UIKit 0x000000010737cac3 -[UITableViewRowData _updateNumSections] + 84 19 UIKit 0x000000010737d4b4 -[UITableViewRowData invalidateAllSections] + 69 20 UIKit 0x00000001071c873b -[UITableView _updateRowData] + 217 21 UIKit 0x00000001071de2b7 -[UITableView noteNumberOfRowsChanged] + 112 22 UIKit 0x00000001071dd9f5 -[UITableView reloadData] + 1355 23 MSUapp 0x00000001057647c6 _TFFC6MSUapp29FavoriteLeaguesViewController11viewDidLoadFS0_FT_T_U_FTO10RealmSwift12NotificationCS1_5Realm_T_ + 166 24 RealmSwift 0x0000000105f37210 _TFF10RealmSwift41rlmNotificationBlockFromNotificationBlockFFT12notificationOS_12Notification5realmCS_5Realm_T_bTSSCSo8RLMRealm_T_U_FTSSS2__T_ + 224 25 RealmSwift 0x0000000105f372af _TTRXFo_oSSoCSo8RLMRealm_dT__XFdCb_dCSo8NSStringdS__dT__ + 111 26 Realm 0x0000000105c0645a -[RLMRealm sendNotifications:] + 986 27 Realm 0x0000000105c068e6 -[RLMRealm commitWriteTransaction] + 262 28 Realm 0x0000000105c06a48 -[RLMRealm transactionWithBlock:] + 120 29 RealmSwift 0x0000000105f34250 _TFC10RealmSwift5Realm5writefS0_FFT_T_T_ + 176 30 MSUapp 0x00000001056d46db _TZFC6MSUapp14DatabaseHelper23removeForSportAndSeasonfMS0_FTCS_5Sport6seasonSS_T_ + 603 31 MSUapp 0x0000000105710d22 _TFFFC6MSUapp11AppDelegate14loadRemoteDataFS0_FT_T_U_FGSaCS_5Sport_T_U_FGSaCS_6League_T_ + 866 32 MSUapp 0x0000000105710dc7 _TTRXFo_oGSaC6MSUapp6League__dT__XFo_iGSaS0___iT__ + 23 33 MSUapp 0x00000001057103d1 _TPA__TTRXFo_oGSaC6MSUapp6League__dT__XFo_iGSaS0___iT__ + 81 34 MSUapp 0x000000010575de90 _TTRXFo_iGSaC6MSUapp6League__iT__XFo_oGSaS0___dT__ + 32 35 MSUapp 0x000000010575ddeb _TFZFC6MSUapp9APIHelper11loadLeaguesFMS0_FTSi18shouldWriteToRealmSb10completionGSqFGSaCS_6League_T___T_U_FCSo6NSDataT_ + 2763 36 MSUapp 0x00000001056f4a0e _TTSf2n_n_n_n_n_d_i_n_n_n___TFFC6MSUapp14JSONDataSource18loadRemoteJsonDataFS0_FTSSCS_19GETParameterBuilderFCSo6NSDataT__T_U_FTCSo12NSURLRequestGSqCSo17NSHTTPURLResponse_GSqS2__GSqCSo7NSError__T_ + 2302 37 MSUapp 0x00000001056f2d59 _TPA__TTSf2n_n_n_n_n_d_i_n_n_n___TFFC6MSUapp14JSONDataSource18loadRemoteJsonDataFS0_FTSSCS_19GETParameterBuilderFCSo6NSDataT__T_U_FTCSo12NSURLRequestGSqCSo17NSHTTPURLResponse_GSqS2__GSqCSo7NSError__T_ + 249 38 Alamofire 0x00000001059e7599 _TTRXFo_oCSo12NSURLRequestoGSqCSo17NSHTTPURLResponse_oGSqCSo6NSData_oGSqCSo7NSError__dT__XFo_oS_oGSqS0__iGSqS1__oGSqS2___dT__ + 25 39 Alamofire 0x00000001059e7461 _TFFFC9Alamofire7Request8responseFDS0_US_18ResponseSerializer___FT5queueGSqCSo8NSObject_18responseSerializerQ_17completionHandlerFTCSo12NSURLRequestGSqCSo17NSHTTPURLResponse_GSqQ0__GSqCSo7NSError__T__DS0_U_FT_T_U_FT_T_ + 737 40 Alamofire 0x00000001059e690e _TPA__TFFFC9Alamofire7Request8responseFDS0_US_18ResponseSerializer___FT5queueGSqCSo8NSObject_18responseSerializerQ_17completionHandlerFTCSo12NSURLRequestGSqCSo17NSHTTPURLResponse_GSqQ0__GSqCSo7NSError__T__DS0_U_FT_T_U_FT_T_ + 206 41 Alamofire 0x00000001059a89d7 _TTRXFo__dT__XFdCb__dT__ + 39 42 libdispatch.dylib 0x000000010938b186 _dispatch_call_block_and_release + 12 43 libdispatch.dylib 0x00000001093aa614 _dispatch_client_callout + 8 44 libdispatch.dylib 0x0000000109392a1c _dispatch_main_queue_callback_4CF + 1664 45 CoreFoundation 0x00000001065741f9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 46 CoreFoundation 0x0000000106535dcb __CFRunLoopRun + 2043 47 CoreFoundation 0x0000000106535366 CFRunLoopRunSpecific + 470 48 GraphicsServices 0x000000010cc17a3e GSEventRunModal + 161 49 UIKit 0x00000001070f08c0 UIApplicationMain + 1282 50 MSUapp 0x000000010570f857 main + 135 51 libdyld.dylib 0x00000001093df145 start + 1 52 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException

Esta pila de llamadas me permite suponer que se debe a mi acceso de escritura en el método generateLeagueList de FavoriteLeaguesViewController. El siguiente es su cuerpo:

var favorites = FavoritesHelper.sharedInstance.favoriteLeagues favorites.sort { $0.sport < $1.sport } for favorite in favorites { // Add to array, which we can later use for cellForRowAtIndexPath }

favorites es del tipo [League] , donde League es un objeto de Realm. Supongo que la excepción se produce porque estoy accediendo a las propiedades de los objetos de League , que se han eliminado de la base de datos Realm mientras tanto (porque la llamada a API que se inició en AppDelegate ya está terminada).

Mi pregunta es: ¿cómo puedo evitar que esto suceda? ¿Cómo puedo asegurarme de que no haya más acceso de escritura / lectura a ninguno de los objetos de League antes de eliminarlos?


El problema estaba en mi clase de FavoritesHelper . Tenía tanto una propiedad favoriteLeagues LegaID como una propiedad de favoriteLeagues . Siempre los configuré a los dos y usé los ID para uso interno y la otra propiedad para cuando quiera datos de estas ligas.

Esto significaba que todas las ligas favoritas eran constantemente referenciadas por la propiedad de las estrellas favoriteLeagues (del tipo [League] ), lo que bloqueaba la aplicación cuando quería buscarlas después de que se invalidaran.

Lo que he hecho para arreglar esto, fue cambiar las propiedades de mis Ligas favoriteLeagues a una propiedad calculada de la siguiente manera:

var favoriteLeagues: [League] { get { var leagues = [League]() for id in favoriteLeagueIDs { if let league = realm.objectForPrimaryKey(League.self, key: id) { leagues.append(league) } } return leagues } }

Ahora las ligas ya no se referencian y simplemente se cargan de la base de datos cuando necesito leerlas. Los objetos invalidados o eliminados no se cargan debido a la instrucción if let (el Realm.objectForPrimaryKey(:key:) devuelve nil en tal caso).


En mi experiencia, si intentas usar el objeto de destino (que deseas eliminar) después de eliminar, la aplicación se bloqueará.

Si quieres activar algunos bloques de código después de eliminar el objeto de reino, simplemente intenta activar ese bloque justo antes de que el objeto se elimine en la memoria. Tratar de usar ese objeto una vez que se haya eliminado de la memoria creará algún problema y bloqueará la aplicación.

Por ejemplo:

try! realm.write { print("deleted word: /(targetObject.word)") realm.delete(targetObject) // targetObject was removed, so don''t try to access it otherwise you gonna got the ''nil'' value instead of object. }


No pude colocar puntos de interrupción dentro del marco de Realm como otros sugirieron, sino que coloqué un punto de interrupción de excepción en todo mi proyecto:

Esto me permitió atrapar un seguimiento de pila adecuado cuando se lanzó la excepción y encontrar mi error.


Obtuve una manera realmente agradable de atrapar una RLMException dentro de Swift.

Actualmente, Swift no muestra dónde ocurrió una excepción RLMException.

En Realm / RLMUtil.mm: 266, está la definición de RLMException.

Si cambia el código para generar un error rápido,

Xcode ahora puede mostrarle dónde ocurrió la excepción.

Ahora es parte de Swift.

// Realm/RLMUtil.mm:193 static NSException *RLMException(NSString *reason, NSDictionary *additionalUserInfo) { // add some code to generate a swift error. E.g. division-by-zero. int a = 0; if (reason == nil) { a = 1; } NSLog(@"calculating 1 / %d = %f", a, 1 / a); ... remainder of the original code... }


Puede verificar si un objeto ha sido eliminado del Reino llamando a object.invalidated - si devuelve true , entonces se ha eliminado o el Reino se ha invalidado manualmente.


puede llamar isInvalidated invalidated o invalidated para juzgar que el objeto no es válido (SÍ) o no (NO). también puedes escribir un método personalizado para definir lo que es realmente invalidate

busca el documento, veremos una propiedad:

/** Indicates if the object can no longer be accessed because it is now invalid. An object can no longer be accessed if the object has been deleted from the Realm that manages it, or if `invalidate` is called on that Realm. */ @property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;

el invalidated es de solo lectura, pero ¿qué significa " isInvalidated ?

es igual a - (BOOL)invalidated { return invalidated; } - (BOOL)invalidated { return invalidated; }

significa que puede escribir un método personalizado para definir lo que es realmente invalidate que desea.