I have a really big problem that I can't handle. My app uses iBeacons to show views and load some pics stored in CoreData, but well, thats not the real question.
I'm loading some pics from parse to core data then retrieved from core data to be displayed.
When i change from one view to another i assume that it can increase, but when i quit the view could be possible to release memory? I don't know it I'm explaining it very well, but i hope you can understand me and help me as much as you can.
I'm using Xcode 5.1.1 and iOS 7.1 on my iPad
Now I'm using instruments to try to see what's going on, and this is what i get.
Allocations:
I think i'm not doing it wrong, loading images like this, dunno what is the problem :_(
self.itemsSection1 = [[NSMutableArray alloc] init];
self.generalImages1 = [[NSMutableArray alloc] init];
[self fillArraysWithItems:self.itemsSection1 section:#"1"];
[self fillArraysWithGeneralImages:self.generalImages1 section:#"1"];
self.itemImages = [NSArray
arrayWithObjects:[UIImage imageWithData:self.itemsSection1[0][#"image"]],
[UIImage imageWithData:self.itemsSection1[1][#"image"]],
[UIImage imageWithData:self.itemsSection1[2][#"image"]],
[UIImage imageWithData:self.itemsSection1[3][#"image"]],
[UIImage imageWithData:self.itemsSection1[4][#"image"]], nil];
for (int i=0; i<self.generalImages1.count; i++) {
[self.itemSliderImages addObject:[UIImage imageWithData:self.generalImages1[i][#"image"]]];
}
generalImage.image = [UIImage imageWithData:self.generalImages1[0][#"image"]];
self.img_elements.image = generalImage.image;
self.navBar_title.title = #"Catering";
FillArraysWithItems:
-(void)fillArraysWithItems: (NSMutableArray*)item section:(NSString*)section{
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Item" inManagedObjectContext:delegate.managedObjectContext];
NSFetchRequest *fetchedRequest = [[NSFetchRequest alloc]init];
[fetchedRequest setEntity:entity];
self.allItemInfo = [[delegate.managedObjectContext executeFetchRequest:fetchedRequest error:nil] mutableCopy];
NSLog(#"\n\nAllItems:%#\n", self.allItemInfo);
for (NSManagedObjectContext *obj in self.allItemInfo) {
//Save data from CoreData to arrays
NSLog(#"\n\nObject:\n%#", obj);
NSString *micro = #"micro_off.png";
NSString *oven = #"oven_off.png";
NSString *recycle = #"recycle_off.png";
NSString *biodeg = #"biodeg_off.png";
NSString *liquid = #"liquid_off.png";
NSString *perso = #"perso_off.png";
NSLog(#"\n\nName:%#\nRef:%#\nPricePack:%#\nUnitPrice:%#\nunitsPack:%#",[obj valueForKey:#"name"], [obj valueForKey:#"reference"],[obj valueForKey:#"pricePack"], [obj valueForKey:#"priceUnity"], [obj valueForKey:#"unitsPack"]);
NSLog(#"\n\nMicro:%#\nOven:%#\nRecycle:%#\nBiodeg:%#\nLiquid:%#\nPerso:%#\n", [obj valueForKey:#"micro"], [obj valueForKey:#"oven"], [obj valueForKey:#"recycle"], [obj valueForKey:#"bio"], [obj valueForKey:#"liquid"], [obj valueForKey:#"perso"]);
if ([[obj valueForKey:#"section"] isEqual:section]) {
if ([[obj valueForKey:#"micro"] isEqual: #1]) {
micro = #"micro_on.png";
}
if ([[obj valueForKey:#"oven"] isEqual: #1]) {
oven = #"oven_on.png";
}
if ([[obj valueForKey:#"recycle"] isEqual: #1]) {
recycle = #"recycle_on.png";
}
if ([[obj valueForKey:#"bio"] isEqual: #1]) {
biodeg = #"biodeg_on.png";
}
if ([[obj valueForKey:#"liquid"] isEqual: #1]) {
liquid = #"liquid_on.png";
}
if ([[obj valueForKey:#"perso"] isEqual: #1]) {
perso = #"perso_on.png";
}
[item addObject:#{#"name": [obj valueForKey:#"name"],
#"pricePack": [obj valueForKey:#"pricePack"],
#"priceUnity": [obj valueForKey:#"priceUnity"],
#"reference": [obj valueForKey:#"reference"],
#"unitsPack": [obj valueForKey:#"unitsPack"],
#"micro": [UIImage imageWithContentsOfFile:micro],
#"oven": [UIImage imageWithContentsOfFile:oven],
#"recycle": [UIImage imageWithContentsOfFile:recycle],
#"bio": [UIImage imageWithContentsOfFile:biodeg],
#"liquid": [UIImage imageWithContentsOfFile:liquid],
#"perso": [UIImage imageWithContentsOfFile:perso],
#"image": [UIImage imageWithContentsOfFile:[obj valueForKey:#"image"]]}];
}
}
NSError *error;
BOOL isFetched = [delegate.managedObjectContext save:&error];
NSLog(#"Arrays successfully filled: %d", isFetched);
}
And this is the error I get when [item addObject...
2014-06-18 09:25:50.176 IBKS[383:60b] -[_PFExternalReferenceData stringByDeletingPathExtension]: unrecognized selector sent to instance 0x14d51f50
2014-06-18 09:25:50.178 IBKS[383:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_PFExternalReferenceData stringByDeletingPathExtension]: unrecognized selector sent to instance 0x14d51f50'
*** First throw call stack:
(0x2f8f1f0b 0x3a3cece7 0x2f8f5837 0x2f8f4137 0x2f843098 0x3213d13f 0x3213d107 0x3213d0dd 0x3213d0ab 0x322487e5 0xd2fe5 0xa76a5 0x32125a53 0x32125811 0x321cf043 0x3220bc4b 0x3220a57d 0x322095f9 0xa01cb 0x9debf 0x2fdb6e91 0x2fdb1aeb 0x2fdab081 0x2f8bd01d 0x2f8bc397 0x2f8bb001 0x2f825769 0x2f82554b 0x3475f6d3 0x32184891 0x9a5ed 0x3a8ccab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
Hope anyone can help.
Thanks
Related
When processing a json response I a get the below error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DADGList setDescription:]:
unrecognized selector sent to instance 0x7ae88880'
The class it crashed on:
#implementation DADGList
-(id)copy
{
DADGList *list = [[DADGList alloc] init];
list.identifier = self.identifier;
list.name = [self.name copy];
list.description = [self.description copy];
list.created = [self.created copy];
list.itemCount = self.itemCount;
list.shareLink = [self.shareLink copy];
return list;
}
+(DADGList *)listFromDictonary:(NSDictionary *)dictonary
{
DADGList *list = [[DADGList alloc] init];
NSLog( #"%#", dictonary );
list.identifier = [[dictonary objectForKey:#"list_id"] integerValue];
list.itemCount = [[dictonary objectForKey:#"list_items_count"] integerValue];
list.name = [NSString stringWithString:[dictonary objectForKey:#"list_name"]];
list.description = [NSString stringWithString:[dictonary objectForKey:#"list_description"]];
list.created = [[NSDate alloc] initWithTimeIntervalSince1970:[[dictonary objectForKey:#"list_created"] doubleValue]];
list.shareLink = [NSString stringWithString:[dictonary objectForKey:#"list_share_url"]];
return list;
}
and the dictonary that is past to listFromDictonary:
You should rename your description property for something else as this is a field already existing in the iOS echosystem (NSObject if I am not mistaken) and that creates all sort of weird crash like this.
If you are using core data maybe you need to implement the following instance:
Mall(entity: NSEntityDescription.entity(forEntityName: "Mall", in: context)!, insertInto: nil)
Where Mall is my entity and context is my view context.
Hi in my application I am setting the value for NSManagedObject while I am trying to set a value app is crashing.Here is the code and error message.
NSManagedObject *object3 = [threadManagedObjectContext objectWithID:[object1 objectID]] ;
for (int i=0;i<[array1 count];i++)
{
NSDictionary *keyValue=[array1 objectAtIndex:i];
[object3 setValue:[[keyValue allValues] lastObject] forKey:[[keyValue allKeys] lastObject]] ;
}
Error: Terminating app due to uncaught exception 'NSGenericException', reason:was mutated while being enumerated
Can any one please help me.
In your code (not the provided) , you're changing a collection while looping/iterating.
Example (not allowed):
for (MyClass *myClassObj in collectionOfMyClass) {
[myClassObj setClassVar: aVar]
}
Solution:
Make a temporary collection of the objects you want to set. Set all of them back outside of your loop.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
for (MyClass *myClassObj in collectionOfMyClass) {
[tempArray addObject:aVar];
}
[myClassObj setClassVars: tempArray];
You can try below solution for updating the object...
NSManagedObject *object3 = [threadManagedObjectContext objectWithID:[object1 objectID]] ;
int i=0;
for (NSDictionary *keyValue in array1)
{
[[object3 setValue:[[keyValue allValues] lastObject] forKey:[[keyValue allKeys] lastObject]] ;i++;
}
NSError *error;
bool result = [[fetchedResultsController threadManagedObjectContext] save:&error];
if (!result) {
NSLog(#" error saving context, %#, %#", error, error.userInfo);
}
In your code while Looping/Enumerating you are setting value..So it is crashing...!
Hope it helps you....
I keep getting this error when i try to bind a nsobject to a segment control
UserLocation isEqualToString:]: unrecognized selector sent to instance 0x7477a60
2013-01-22 12:44:58.115 Momentum[39936:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UserLocation isEqualToString:]: unrecognized selector sent to instance 0x7477a60'
I have verified that my core data object has data.
NSarray *arrayuserlocation = [[MMIStore defaultStore] loadAllUserLocation];
UISegmentedControl *segControl = [[UISegmentedControl alloc]initWithItems:arrayuserlocation];
[segControl addTarget:self action:#selector(didChangeSegmentControl:) forControlEvents:UIControlEventValueChanged];
[segControl setSegmentedControlStyle:UISegmentedControlStyleBar];
[segControl setTintColor:[UIColor grayColor]];
EDIT
To the answer the question below
- (NSMutableArray *)loadAllUserLocation
{
if (!allItems) {NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *e = [[model entitiesByName] objectForKey:#"UserLocation"];
[request setEntity:e]
NSError *error;
NSArray *result = [context executeFetchRequest:request error:&error];
if (!result) {
[NSException raise:#"Fetch failed"
format:#"Reason: %#", [error localizedDescription]];
}
allItems = [[NSMutableArray alloc] initWithArray:result];
}
return allItems;
It returns an array
I was able to solve my problem by doing the following.
NSArray *arraylocation = [[MMIStore defaultStore] loadAllUserLocation];
NSMutableArray *newarray = [[NSMutableArray alloc] init];
for (UserLocation *user in arraylocation)
{
NSLog(#"%# found", user.locationNm);
[newarray addObject:user.locationNm];
}
And using newarray as the datasource for the segment control.
As I mentioned in comments, the issue is that you are passing userlocation objects instead of NSString or UIImage objects required.
As per the documentation your items array should be "an array of NSString objects (for segment titles) or UIImage objects (for segment images)."
You need to fetch the strings from user location as,
NSarray *arrayuserlocation = [[[MMIStore defaultStore] loadAllUserLocation] valueForKey:#"locationNm"];//use the param name here
This should give you an array of all strings from the array of objects.
The problem is, the arrayuserlocation array should contain NSStrings instead of NSManagedObjects.
The code that's throwing the exception is expecting you to pass it an NSString (this is the object that responds to isEqualToString:). However, you are passing it a UserLocation object. You need to load up arrayuserlocation with strings from the UserLocation object, not just send an array of objects themselves.
I hope this isn't a duplicate question. I can't seem to find anything similar. Most core data questions seem to be about new object creation...
I have a program with a database of around 23,000 items. I'm attempting to create an export/import function to send data to other devices (not linked with iCloud).
The export works just fine, as does the email...
I have the import functioning, but it functions slowly (and, more on this later, doesn't seem to work well with the iPhone 5 or iPad 3)
I have a function that parses the data I'm importing into an NSArray (_importedRows), then I run the following code:
self.managedObjectContext = [(AppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSManagedObjectContext *ctx = self.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"CHECKLIST"
inManagedObjectContext:ctx];
[fetchRequest setEntity:entity];
ImportedData *importedData;
NSString *verify;
NSError *error = nil;
NSManagedObject *updatedObject;
NSArray *matchingItems;
for (int i = 0; i < [_importedRows count]; i++) {
importedData = [_importedRows objectAtIndex:i];
verify = importedData.uniqueID;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"uniqueID == %#", verify]];
[fetchRequest setFetchLimit:1];
matchingItems = [ctx executeFetchRequest:fetchRequest error:&error];
for (updatedObject in matchingItems) {
HUD.detailsLabelText = [NSString stringWithFormat:#"Updating %#" , [updatedObject valueForKey:#"figureName"]];
[updatedObject setValue:importedData.numberOwned forKey:#"numberOwned"];
[updatedObject setValue:importedData.numberWanted forKey:#"wishList"];
[updatedObject setValue:importedData.availableTrade forKey:#"tradeList"];
}
[ctx save:&error];
if (error != nil) {
NSLog(#"error saving managed object context: %#", error);
}
}
Basically, I'm grabbing a core data entity, and then looping through my array checking for matches. When I find a match (the uniqueID predicate), I'm updating the object with the imported data. This code works fine on my iPhone 4s, but rather slowly. 4,000 items takes around 4-5 minutes. Am I doing anything blatantly wrong? Should I be calling the save function more frequently?
As a bonus, for some reason this code almost never works when I test it on an iPhone 5. 9 times out of 10 (and 50% of the time on my iPad 3) I get a
"Jan 14 08:06:44 : * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'"
in the console. Thoughts?
Let me know if more details are needed!
UPDATE:
It seems that handleOpenURL is being called twice... once in applicationdidfinishlaunching
NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
if (url != nil && [url isFileURL]) {
[self.window.rootViewController performSelector:#selector(showWithLabel:) withObject:url afterDelay:6];
}
and once here:
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{ if (url != nil && [url isFileURL]) {
[self.window.rootViewController performSelector:#selector(showWithLabel:) withObject:url];
}
return YES;
}
I have to lave both those in the app delegate, otherwise the function won't always get called (once is for when the application launches, and once if it the application was already in the background, I believe) - I've added a check to prevent it from launching a second time within the showWithLabel thread, but it doesn't seem like that is a very elegant solution...
UPDATE: #mundi advised cleaning up the fetchedresults code as follows:
NSArray *importedIDs = [_importedRows valueForKeyPath:#"uniqueID"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:#"CHECKLIST"
inManagedObjectContext:ctx];
fetchRequest.predicate = [NSPredicate predicateWithFormat:
#"uniqueID in %#", importedIDs];
NSError *error = nil;
NSManagedObject *updatedObject;
NSArray *matchingItems;
matchingItems = [ctx executeFetchRequest:fetchRequest error:&error];
ImportedData *importedData;
for (int i = 0; i < [_importedRows count]; i++) {
importedData = [_importedRows objectAtIndex:i];
for (updatedObject in matchingItems) {
if ([importedData.uniqueID isEqualToString:[updatedObject valueForKey:#"uniqueID"]]) {
HUD.detailsLabelText = [NSString stringWithFormat:#"Updating %#" , [updatedObject valueForKey:#"figureName"]];
[updatedObject setValue:importedData.numberOwned forKey:#"numberOwned"];
[updatedObject setValue:importedData.numberWanted forKey:#"wishList"];
[updatedObject setValue:importedData.availableTrade forKey:#"tradeList"];
}
}
}
[ctx save:&error];
I'm sure it could still be a little cleaner and the actual updating portion (I'm not sure how to do it other than compare each item in the fetchedresults with each item in the initial array to make sure they are updated correctly, but the combined fetchedresults increased the speed tremendously (originally 240 seconds for 4000 items, now between 80-120 seconds)
sorting arrays first, then updating in order speeds it up tremendously yet again:
NSArray *matchingItemsSorted;
matchingItemsSorted = [matchingItems sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [a valueForKey:#"uniqueID"];
NSString *second = [b valueForKey:#"uniqueID"];
return [first caseInsensitiveCompare:second];
}];
NSArray *importedRowsSorted;
importedRowsSorted = [_importedRows sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [a valueForKeyPath:#"uniqueID"];
NSString *second = [b valueForKeyPath:#"uniqueID"];
return [first caseInsensitiveCompare:second];
}];
int i = 0;
for (updatedObject in matchingItemsSorted) {
NSLog(#"do we match? %# : %#", [[importedRowsSorted objectAtIndex:i] valueForKeyPath:#"uniqueID"], [updatedObject valueForKey:#"uniqueID"]);
HUD.detailsLabelText = [NSString stringWithFormat:#"Updating %#" , [updatedObject valueForKey:#"figureName"]];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:#"numberOwned"] forKey:#"numberOwned"];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:#"numberWanted"] forKey:#"wishList"];
[updatedObject setValue:[[importedRowsSorted objectAtIndex:i] valueForKeyPath:#"availableTrade"] forKey:#"tradeList"];
i++;
}
13 seconds or so for 4000 items with the nslog there... the only weird thing now is that when I comment out the nslog, it frequently crashes... is it happening so fast it's breaking core data - when it doesn't crash, it only takes about 4 seconds?
Thanks,
Zack
You have two nested loops. Use this pattern to speed this up:
NSArray *importedIDs = [_importedRows valueForKeyPath:#"uniqueID"];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
fetchRequest.entity = [NSEntityDescription entityForName:#"CHECKLIST"
inManagedObjectContext:ctx];
fetchRequest.predicate = [NSPredicate predicateWithFormat:
#"uniqueID in %#", importedIDs];
Like this you can fetch one array with all matching items.
I'm having a real bad time with this core data error.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'
My app and code all works fine except occasionally when calling requests very quickly. It happens when I'm trying to break the app.
Going from one screen to the next, downloading data and executing fetch requests.
I know it has something to do with threading and core data.
I'm calling this piece of code from a background thread, with it's own managed object context.
+ (AN_User *)updateWithRecord:(NSDictionary *)record moc:(NSManagedObjectContext *)moc{
NSNumber *userID = nil;
NSString *username = nil;
if([record objectForKey:#"user_id"]){
userID = [NSNumber numberWithInt:[[record objectForKey:#"user_id"] intValue]];
}else if([record objectForKey:#"id_member"]){
userID = [NSNumber numberWithInt:[[record objectForKey:#"id_member"] intValue]];
}
if([record objectForKey:#"username"]){
username = [NSString stringWithFormat:#"%#", [record objectForKey:#"username"]];
}else if([record objectForKey:#"member_name"]){
username = [NSString stringWithFormat:#"%#", [record objectForKey:#"member_name"]];
}
if(!userID||!username){
return nil;
}
__block AN_User *user = nil;
[moc performBlockAndWait:^{
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"AN_User" inManagedObjectContext:moc];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(user_id == %#) OR (username == %#)", userID, username];
[request setPredicate:predicate];
if([moc countForFetchRequest:request error:nil]==0){
user = (AN_User *)[NSEntityDescription insertNewObjectForEntityForName:#"AN_User" inManagedObjectContext:moc];
}else{
NSArray *fetchResults = [moc executeFetchRequest:request error:nil];
if(fetchResults.count>0){
user = [fetchResults objectAtIndex:0];
}
}
if(user){
user.user_id = userID;
user.username = username.lowercaseString;
//Parse profile image url
NSString *avatar = [record objectForKey:#"avatar"];
NSString *fileName = [record objectForKey:#"filename"];
if([avatar isKindOfClass:[NSString class]]&&avatar.length>0){
user.profile_image_url = [NSString stringWithFormat:#"%#", avatar];
}else if([fileName isKindOfClass:[NSString class]]&&fileName.length>0){
user.profile_image_url = [NSString stringWithFormat:#"http://www.example.com/forum/avs/%#", fileName];
}
if([record objectForKey:#"gpbp_respect"]){
user.respect = [NSNumber numberWithFloat:[[record objectForKey:#"gpbp_respect"] floatValue]];
}
}
}];
return user;
}
I understand it's probably hard to tell from just this, but can anyone tell me if I'm doing anything wrong, with these requests, that is immediately obvious.
If you scroll a table that calls core data on a b/g thread, it happens and Core Data expects to have the context all on one thread.
Another SO poster worked around this by creating a MOContext per thread, but I don't like the idea of CRUD on multiple threads so I just put a dispatch_async (dispatch_get_main_queue(), ) wrapping function around my code. So far no crashes, but it's rare so I am not absolutely certain on this.