I'm having some troubles trying to save a singleton object to the iPhone disk.
The object is a collection of 2 arrays, which contain the faved posts and faced jobs.
Basically --> Favorites = arrayOfFavedPosts + arrayOfFavedJobs
Now I am trying to save the Favorites object, so that the once faved posts or jobs can be read from the disk.
my Faves.m file.
Error:
2012-04-26 14:56:56.957 FirstDesign_test2[666:10403] -[Post encodeWithCoder:]: unrecognized selector sent to instance 0x6c74a80
This error fires up when I call the saveToDisk method when I add a new object to one of the arrays...
Some help would be really appreciated!
Thanks in Advance
You need to adopt and implement the NSCoding protocol on your Post class (and presumably on your Job class).
NSCoding Protocol Reference
Archives and Serializations Programming Guide: Encoding and Decoding Objects
Related
I'm developing a small weak datastructures framework.
A collection of weakely wrapped object has a remove() method.
Inside the method i will delete an object if present and eventually purge the wrappers containing nil references.
The problem raise in the case the weakCollection.remove(object) is called inside a object.deinit() (may happen indirectly).
In this case (since i need to make a copy for comparison reasons) i will have a SIGABORT due to trying to reference an object that is being deallocated and this is forbidden in swift.
Cannot form weak reference to instance (0x608000199710) of class
XXX. It is possible that this object was
over-released, or is in the process of deallocation.
Normally i'd just document it, throw an error or a warning and skip. But i'd like to be safe about this and only remove an object when is not in "releasing" state.
One way would be reading the referenceCount, but in swift is not a good idea. Most other reflection/meta techniques i can think of are too expensive.
Plus: Another thing i'd really appreciate to know is if there is any notification/kno/observer i can connect to in order to be notified when object is being released.
When i call the method:
- (void)removeObjectFromMediaAtIndex:(NSUInteger)idx;
which is one of the default methods in a file created as a core data object, i'm getting an error of unrecognized selector sent to instance. Anybody know why this might be happening?
Ensure that your NSManagedObject sublcass instance was created using an NSManagedObjectContext and not directly. Instead of leveraging #synthesize for properties, NSManagedObject sublcasses leverage the #dynamic keyword which indicates the accessors will be created at runtime - in this case, by the NSManagedObjectContext. They will not be there if you create the object instance using something like alloc]init];
It is a notorious Core Data bug. It is almost 2-year old but sadly it is still there. See this post: Exception thrown in NSOrderedSet generated accessors.
It sounds like you may have altered your data model without altering the classes, or vice-versa. Or perhaps one of your team members did (my team quickly learned about this danger). Another possibility is that the reference you are using is not actually the class you think it is. Sometimes if you overrelease an object, another object will occupy the previous memory space but it will not be the correct class.
However, this doesn't look like a default method. The default methods I am used to seeing are add object, remove object, change to a new NSSet, and one more that I can't quite remember off the top of my head. However, if you got the CoreData object to use an NSArray instead it would make sense.
I have three classes, A, B and C. A is the main class.
When the user wants to see the list of all objects that were purchased, Class B is called from A and shows the list of objects in a core data entity.
Inside class B, the user can buy new objects (in-app purchase). When the user wants to buy another object, class C is called.
When class C is called, a new object is created on the core data entity using
anObject = [NSEntityDescription insertNewObjectForEntityForName:#"Objects" inManagedObjectContext:context];
this object is then assigned to a local reference on Class C, using something like
self.object = anObject;
this object variable was declared like this:
.h
MyObjects *object;
#property (nonatomic, retain) MyObjects *object;
and #synthesized on .m
MyObjects is a core data class representing the entity.
In theory, object will retain anything assigned to it, so the line self.object = anObject I typed previously will retain anObject reference on self.object, right?
The problem is that when I try to access self.object in the same class after buying the new object, I receive an error "CoreData could not fulfill a fault for XXX", where XXX is exactly self.object.
At no point in the code there's any object removal from the database. The only operation to the database I could identify was a saving operation done by another class moments before the crash. The save is done by something like
if (![self.managedObjectContext save:&error]) ...
Is there any relation? what may be causing that?
CoreData manages the lifetime of managed objects and you should not retain and release them. If you want to keep a reference to the object so that it can be retrieved later then you have to store the object's id (obtained using -[NSManagedObject objectID]). Then use that to retrieve the object later using -[NSManagedObjectContext objectWithID:].
Make sure you understand about CoreData faulting. Read the documentation.
I had a similar issue a few days ago (using NSFetchedResultsController) where I was placing my fetchedObjects into an array and gathering attributes to populate tables from the array objects. It seems that if the objects in the array are faulted, you cannot unfault it unless you are acting on the direct object. In my case, I solved the issue by taking the lines of code in question and calling [[_fetchedResultsController objectAtIndexPath:indexPath] someAttribute]. I would assume that doing something similar would fix your problem as well. It seems a bit tedious to need to fetch from the managedObjectContext to obtain a faulted value, but this was the only way I could personally get past the issue.
Core Data is responsible for managing the lifetime of managed objects in memory. It's really important to understand Managed Object Contexts - Read the documentation.
Apple also provides an entire troubleshooting section here, and it contains among other things the causes for your error. But it's really only useful if you understand how core data works.
Most likely error is that the object you are saving does not belong to the managed object context.
Say you use the same object on different threads and those different threads use different managed object context, then this will happen.
What is __NSArrayI and __NSArrayM?
__NSArrayI(or M) cause "unrecognized selector" error.
How to convert to NSArray?
I did test to parse json, twitter api.
http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=twitterapi
==> works fine. parsed object is NSCFDictionary class.
(This dictionary contains __NSArrayM class)
http://api.twitter.com/1/statuses/user_timeline.json?&screen_name=twitterapi
==> error. parsed object is __NSArrayM class.
__NSArrayI is a code-word for an immutable array - that is, a "regular" NSArray which you cannot change.
__NSArrayM is a code-word for a mutable array - that is, NSMutableArray. In NSMutableArray, you can add and remove items.
These are classes of the private api. There is a project where you can see all classes of the private api. You are not allowed to use them inside an app for the app store but sometimes it is useful too see how to access the objects and also what kind of object it is. They cannot be converted. I think, getting these kind of objects inside the debugger is just the representation of internal classes, for the classes you are using inside your project. Knowing what kind of class it is, lets you also understand where to look for the problem inside your code.
Here you can see a short lookup of both:
__NSArrayI
__NSArrayM
It is private classes. You shouldn't want to access them or moreover convert them.
If I'm not mistaken NSArray is subclass of _NSArray.
If you are adding/removing some objects to/from your array check that it is of mutable type : NSMutableArray
I have made an class which conforms to the NSCoding protocol and does all the encode and decode stuff.
For my app, I simply want to persist an object from that class to the device and the next time when the app launches, I want to load that object back into memory.
Basically it's just an class which holds some user input information. For example the user starts writing a text but then quits the app. Next time I want to load that data object.
I guess I need NSKeyedArchiver? Is there a good tutorial on this? How do I do that?
Yes you need NSKeyed(Un)Archiver. These 2 classes can convert your object to/from NSData which you can save/load it as a file.
To save your object to a file:
if (![NSKeyedArchiver archiveRootObject:your_object toFile:#"filename.plist"])
// save failed.
To read the object from a file:
id your_object = [NSKeyedUnarchiver unarchiveObjectWithFile:#"filename.plist"];
if (your_object == nil)
// read failed.