Realm throwing RLMException when checking equality on property - ios

Whenever I try to check equality between a property on a Realm object and a NSInteger, it throws the following exception:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
However I am not modifying the object, just accessing it. Do I have to start a write transaction to check equality?
If I put a breakpoint right at the start of the if statement, the next step in throws the exception.
//message is a RLMObject stored in a RLMResults array
if (message.status == 3 || message.status == 4) {
NSLog(#"Message status: %ld", (long)message.status);
}

The issue was that I was querying and modifying the RLMObject elsewhere in the setup of another view controller. This was causing the exception to be thrown. My fault for not looking closely at what my other code was doing.

Related

how to solve 'Object has been deleted or invalidated.' Realm exception

i have different realm objects in different ViewControllers and from my settingViewController i'm deleting all the data of app (the realm stored objects ) its working fine but when i move back to those viewControllers i got this exception :
Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'
*** First throw call stack:
(0x180c0adb0 0x18026ff80 0x100a13e7c 0x1001bd54c 0x1001be77c 0x1860c288c 0x1860c2c3c 0x185eb78e8 0x185d775b4 0x185eb6d34 0x192375f40 0x185ef1c94 0x192375ccc 0x1001b97ac 0x1001bbe4c 0x1860bf030 0x1860bf198 0x1860ae298 0x1860c3c64 0x185e548c4 0x185d641e4 0x1836f698c 0x1836f15c8 0x1836f1488 0x1836f0ab8 0x1836f0818 0x1836e9ddc 0x180bc0728 0x180bbe4cc 0x180bbe8fc 0x180ae8c50 0x1823d0088 0x185dd2088 0x100121cc8 0x1806868b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
i know its happening because system (kernel , iOS) dont knows that i've deleted those Realms Objects and system is trying to use that data which is not exists anymore (Correct me if i'm wrong) , any one can guide me on how i can fix this problem ???
I suggest you to make notification before deleting all your data to all view controllers, that manipulate with it:
Push notification from your settingViewController before wipe
Subscribe to this everywhere you need to clear objects.
delete references
perform clean in your settingViewController.
Or, other way - implement delegate pattern for your purpose. The idea is the same.
Hope this helps.

Realm - Catch an exception in realm.create

How can I catch an Exception in create method from Realm's framework? I am trying like this but I never catch the Exception about duplicate primary keys.
do {
try! realm.write() {
let person = realm.create(Person.self, value: ["Jim", 0])
person.age.value = 30
}
}
catch {
print("Error")
}
The error:
realm1[922:26059] *** Terminating app due to uncaught exception 'RLMException',
reason: 'Can't set primary key property 'name' to existing value 'Jim'.'
do {...} catch {...} is only for catching Errors that are thrown from swift methods, it is not for catching exceptions.
The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from.
- LLVM Docs
So if an exception is being thrown, it generally means that you are not checking something before an operation. In this case, you should check for a Person that already exists with that primary key then update it or create a new Person if one doesn't already exist.

Is the save: method thread-safe?

In short
Can I call
[moc performBlockAndWait:^{
[moc save:NULL] ;
}];
from different threads at the same time?
In long
I add a crash similar to this one, namely:
Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2011-06-15 11:36:59.864 myApp[457:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
*** Call stack at first throw:
The program crashes on this command:
[moc performBlockAndWait:^{
[moc save:NULL] ;
}];
As I launch the same process (with difference parameters) to as many threads as possible (with the help of NSOperationQueue), this command might be called by different threads as the same time.
Could that be a problem? Or the method performBlockAndWait: already deals with that?
I ask you the question to know if I need to create a singleton that would manage the saving to the moc.
-save: must be called from the thread/queue that created the context.
calling -performBlockAndWait: does avoid calling it from the wrong thread.
You must pass in a NSError to the -save: method and you need to watch the result of the -save: to determine if an error is occurred. That is your singular way of knowing if an error occurred. Passing in NULL is asking for trouble.
The error you are currently seeing is not caused from the save directly. It is most likely caused because you are listening to NSManagedObjectContextDidSaveNotification somewhere else and doing something incorrect there. Search your code for that constant and review the code associated with it.

Crash with "Collection ... mutated while being enumerated"

I got this error after a crash:
malloc: *** error for object 0x75617b4: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
2013-02-05 19:15:44.950 BusinessIdea[3171:15e03] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSSetM: 0x72dc5c0> was mutated while being enumerated.'
I am not familiar with this error. Any idea what it could be?
The whole 'modified while being enumerated' error means you are probably trying to delete something from a set while iterating over it. For example
for(NSString *str in array){
if([str isequalToString:#"delete me"]){
[array removeObject:str]; //this will cause a problem,
}
}
If you want to use the fast enumeration loop, you need to build a list of items you want to remove, and then delete them after the iteration step. Alternatives are to use a traditional indexed for loop if you want to remove items in the loop body.

Serialization array of custom objects iOS

I know there is a lot of resources about that here but yet, I can't find what's going wrong with my code:
I have a class Level and two subclasses of Level: GameLevel and TransitionLevel. Each of this class implements the NSCoding protocol.
Then, I've got an array of Level (so it contains both classes of GameLevel and TransitionLevel). Saving the archive seems to work fine :
NSString *archivePath = [DOCUMENT_DIRECTORY stringByAppendingPathComponent:#"levels.archive"];
[NSKeyedArchiver archiveRootObject:levels toFile:archivePath];
Note that levels is the array I want to save. I can see the file, it's created and seems to contains what it's supposed to contain.
But when I want to retrieve this array :
NSString *archivePath = [DOCUMENT_DIRECTORY stringByAppendingPathComponent:#"levels.archive"];
levels = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
I've got this exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
I'm not sure what I'm missing here.
Either your implementation of initWithCoder: returns nil, either some part of your code tries to insert a nil value into an array.
You may go in the Breakpoint Navigator (⌘6) and add an Exception Breakpoint. Then, when the application raises an exception, the Debug Navigator will display the stack of the functions and methods currently executed. This would allow you to know precisely which method is trying to insert nil into an array.

Resources