MGTwitterEngine and its Supported Arrays - iphone

This is my first time posting. I have been afraid to post anything since I am a noob with C++ but I do have to say I seem to be catching on fairly quick since I am an experienced html, css, javascript developer.
Ok so I am working on this project that implements twitter and Matts TwitterEngine and things are starting to come together. I have a tableview collecting the timeline of the user who signs in. You can make tweets and see the timeline but I am running into a few problems while trying to incorporate the "#"user" attribute.
I have come to conclusion that it is because it is a NSDictionary with several arrays within in it itself. For example #user consist of User, scree_name, ect so here is some code to maybe see if anybody can help me sort this out a little.
In the .h file of a NSObject I will call out a
-(NSString*)author;
In the .m file
#implementation Tweet
-(id)initWithTweetDictionary:(NSDictionary*)_contents {
if(self == [super init]) {
contents = _contents;
[contents retain];
}
return self;
}
-(NSString*)author {
return [[contents objectForKey:#"user"] objectForKey:#"screen_name"];
}
Now this is where I call it to a View and believe I have issues becuase I am still learning Arrays and Mutable Arrays and not sure what to call.
In my TwitterViewController.h
I first obviously import SA_OAuth engine and controller which work fine then I use two MutableArrays like below
MGTwitterEngine *_twitter;
SA_OAuthTwitterEngine *_engine;
NSMutableArray *tweets;
NSMutableArray *authors;
in the twitterview.m I import the first .h and then call out
//Connect to twitter API
- (void)viewDidAppear:(BOOL)animated {
if(_engine) return;
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = #"key here =P";
_engine.consumerSecret = #"secret here =P";
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else {
tweets = [[NSMutableArray alloc] init];
authors = [[NSMutableArray alloc] init];
Then I returns the count of that MutableArray and try to display it next to the tweets so it shows the persons screen_name of the actual tweet on the timeline
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
//add subtitle
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
[cell.textLabel setNumberOfLines:7];
[cell.textLabel setText:[(Tweet*)[tweets objectAtIndex:indexPath.row] tweet]];
//-------THIS IS WHERE I KEEP GETTING A SIGBRT DURING LOAD "dump saying return count 0-----------[cell.textLabel setText:[(Tweet*)[authors objectAtIndex:indexPath.row] author]];------
//[cell.detailTextLabel setText:[(Tweet*)[retweetCount objectAtIndex:indexPath.row] reTweetCount]];
#pragma mark SA_OAuthTwitterController Delegate
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
NSLog(#"Authenticated with user %#", username);
tweets = [[NSMutableArray alloc] init];
authors =[[NSMutableArray alloc] init];
[self updateStream:nil];
}
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {
tweets = [[NSMutableArray alloc] init];
for(NSDictionary *d in statuses) {
NSLog(#"See dictionary: %#", d);
Tweet *tweet = [[Tweet alloc] initWithTweetDictionary:d];
[tweets addObject:tweet];
[retweetCount addObject:tweet];
[tweet release];
}
[self.tableView reloadData];
}
- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier {
authors = [[NSMutableArray alloc] init];
for (NSDictionary *d in userInfo) {
NSLog(#"See dictionary: %#", d);
Tweet *tweet = [[Tweet alloc] initWithTweetDictionary:d];
[authors addObject:tweet];
[tweet release];
}
[self.tableView reloadData];
}
So like I said the "tweets" are working and I can add in other objects by addObject method such as retweet count but I can not for the life of me figure out why I cant get the User screen name to display in the cell!!!
I also eventually want to Async with the avatars and add a RT button so if anyone has any suggestions on an EASY way to implement those that would be great too!
I appreciate any help I can get !!! Thanks hope to hear from some one soon to help enlighten me about NSDictionary, NSArrays and MutableArrays cause I believe thats were the problem lays. Or maybe I am just not populating the table correctly whatever it is man I am stumpped and could use some help!
Thanks sincerely
Anthony
DUMP:
2011-05-29 03:27:21.477 ThemeCatcher[10409:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x01524be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x016795c2 objc_exception_throw + 47
2 CoreFoundation 0x0151a6e5 -[__NSArrayM objectAtIndex:] + 261
3 ThemeCatcher 0x00024498 -[TwitterVeiwController tableView:cellForRowAtIndexPath:] + 600
4 UIKit 0x008037fa -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
5 UIKit 0x007f977f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
6 UIKit 0x0080e450 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
7 UIKit 0x00806538 -[UITableView layoutSubviews] + 242
8 QuartzCore 0x004a8451 -[CALayer layoutSublayers] + 181
9 QuartzCore 0x004a817c CALayerLayoutIfNeeded + 220
10 QuartzCore 0x004a137c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
11 QuartzCore 0x004a10d0 _ZN2CA11Transaction6commitEv + 292
12 QuartzCore 0x004d17d5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
13 CoreFoundation 0x01505fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
14 CoreFoundation 0x0149b0e7 __CFRunLoopDoObservers + 295
15 CoreFoundation 0x01463bd7 __CFRunLoopRun + 1575
16 CoreFoundation 0x01463240 CFRunLoopRunSpecific + 208
17 CoreFoundation 0x01463161 CFRunLoopRunInMode + 97
18 GraphicsServices 0x01f42268 GSEventRunModal + 217
19 GraphicsServices 0x01f4232d GSEventRun + 115
20 UIKit 0x0079e42e UIApplicationMain + 1160
21 ThemeCatcher 0x00002c29 main + 121
22 ThemeCatcher 0x00002ba5 start + 53
23 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Current language: auto; currently objective-c
(gdb)
UPDATED!!!!!! Want to post my solution incase others read this. I hate browsing post and users find their awnser but do not share their solution to help others in the future. So I wont be that guy and tell you all how I got this to work!
Solution:
First Correctly call out your Arrays like Danny talks about below do NOT follow the method I was it can cause issue for yourself later down the road. " I still used MutableArray on both call but will attempt to change in the near future.
Now make sure all Arrays are formatted properly and "connect your dots" =P
But here is the Kicker! Below is a part of MGTwitterEngine that explains my issue. At first I was calling a integer of "1" which the engine thought I was trying to get one "screen_name" for a whole array of users so obviously it would though a SIGABRT and say WTH are you trying to do here! =P
Just want to clarify what I said earlier about Integers and defining the user. In
MGTwitterRequestTypes.h towards the bottom theres this line of code:typedef enum _
MGTwitterResponseType {
MGTwitterStatuses = 0, // one or more statuses
MGTwitterStatus = 1, // exactly one status
MGTwitterUsers = 2, // one or more user's information
MGTwitterUser = 3, // info for exactly one user
MGTwitterDirectMessages = 4, // one or more direct messages
MGTwitterDirectMessage = 5, // exactly one direct message
MGTwitterGeneric = 6, // a generic response not requiring parsing
MGTwitterMiscellaneous = 8, // a miscellaneous response of key-value pairs
MGTwitterImage = 7, // an image
#if YAJL_AVAILABLE
MGTwitterSearchResults = 9, // search results
#endif
} MGTwitterResponseType;
// This key is added to each tweet or direct message returned,
// with an NSNumber value containing an MGTwitterRequestType.
// This is designed to help client applications aggregate updates.
define TWITTER_SOURCE_REQUEST_TYPE #"source_api_request_type"
I hope I i have help others to accomplish adding scree_name...and basically you can use this for any "text" information within there such as ReTweet Counts ect... ect...
Now I need to figure out how to load thier profile images in the tableview .... I have it loading the images with this line of code but it wont load in the table view for some odd reason. It even pushes the text over correctly like their is an image there but there is not one
Any Suggestions on this would be greatly appreciated!!!
NSString *imageurl = [avatarsURL objectAtIndex:0];
NSLog(#"http://api.twitter.com/1/users/profile_image/username.json");
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];
UIImage *tableImage = [[UIImage alloc] initWithData:imageData];
[cell.imageView setImage:tableImage];
CGSize imageSize = CGSizeMake(45,40);
UIGraphicsBeginImageContext(imageSize);
CGRect imageRect = CGRectMake(0.2, 0.1, imageSize.width, imageSize.height);
[tableImage drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
....I get no errors at all just this in the dump " I have to remove the HyperLinks because spam issues and I am a new member....FYI"
2011-05-29 17:26:02.950 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.980 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.981 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.982 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.983 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.984 ThemeCatcher[2974:207]
http:api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.985 ThemeCatcher[2974:207]
http://api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:02.987 ThemeCatcher[2974:207]
http://api.twitter.com/1/users/profile_image/username.json
2011-05-29 17:26:06.550 ThemeCatcher[2974:207] Request Suceeded: BF0E18DB-A2CC-4823-AC02-
6E182127BBF7
I can leave 2 =P

Okay, there are a few problems (I'll save the memory-management related stuff for last):
General Problems
First of all, how does your implementation of numberOfSectionsInTableView: and tableView:numberOfRowsInSection: look like?
Next, every time your viewDidAppear: is called and you are already logged in you basically forget about all the old tweets: tweets = [[NSMutableArray alloc] init];
But what's even more problematic, is that you do so every time you receive data, as well:
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {
tweets = [[NSMutableArray alloc] init]; // <= No!
...
}
And then there is this problem which I don't understand because I don't know the library: What's the difference between your authors and yout tweets? (Both are arrays of tweets — frankly, I don't see the point.)
If understood your crash correctly, it happens when you try to retrieve a tweet from the authors array and you assume that your authors array has at least the same number of objects in it, as the tweets array.
I don't know MGTwitterEngine well, but from what I infer from its documentation, userInfoReceived:forRequest: will only be called after you sent an explicit request for a users profile.
So it doesn't come as a surprise, that your assumption is apparently wrong.
Furthermore, you should be able to get all the info you need to display a tweet in the timeline from the tweet itself anyway (well except the actual image-data of the avatar, that is).
Memory Management
You are leaking every tweet you will ever receive:
Although you take care of correctly releasing every individual tweet after adding it to the tweets or authors array (good), you forget about those arrays whenever new data comes in. You probably shouldn't replace the entirety of said arrays in the first place and — instead — simply add the new stuff to them, but since you decided to go that route, make sure to release the old array before you assign the new one.
Personally, I'd suggest a different approach and create the tweets array only once in initWithStyle:, (and don't bother creating an authors array at all) only adding to and removing from it as needed — properly disposing of it in dealloc and calling removeAllObjects on it, when a user logs out (if you don't dispose of the view controller entirely, in this case).

Related

iDevice camera shows black instead of preview

I am developing an app that captures images from iDevice's camera and upload it to web service.
NO problem everything is working fine except the device's camera. Device's camera is driving my crazy. I am using below code to allow user to capture images. Sometimes camera shows preview and sometimes doesn't. Instead of preview is just shows complete darkness on screen. If I switch from rear to front camera is starts working fine. I have even trying deleting all background apps from device and clearing as much memory as I could; still no luck and I am stuck. :(
- (IBAction)addNewImage:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
// Take picture from camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// set no to take as much pictures as user want.
imagePicker.showsCameraControls = YES;
// Show user the camera
[self presentModalViewController:imagePicker
animated:YES];
}
else
{
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePicker
animated:YES];
}
}
I have a customer who had this issue. They must have selected to not allow access to the camera. We had to change the camera privacy setting for the app in Settings. When we switched that back on, no more black camera screen.
I was facing the same issue in iOS7 for around a month, After a long long head breaking code review of the entire app, i was able to identify the problem.
I was enumerating an
IBOutletCollection(UILabel) NSArray *staticLabelsCollection;
array Concurrently updating the labels texts, which got executed simultaneously on multiple threads.
[self.labelsArr enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
UILabel * label = (UILabel*)obj;
label.text=[NSString stringWithFormat:#"%d",idx+2];
}];
This created the problem of updating the UIKit elements on other than main thread.
I was able to catch the this issue by enabling the environment variable CA_DEBUG_TRANSACTIONS=1 in Xcode which generated warnings in device console
Nov 20 18:40:26 iPad2 CameraTest[1757] <Warning>: CoreAnimation: warning, deleted thread with uncommitted CATransaction; created by:
0 QuartzCore 0x32a553b3 <redacted> + 266
1 QuartzCore 0x32a55269 <redacted> + 224
2 QuartzCore 0x32a56871 <redacted> + 24
3 QuartzCore 0x32a56eed <redacted> + 40
4 QuartzCore 0x32a619ed <redacted> + 412
5 QuartzCore 0x32a6184b <redacted> + 46
6 QuartzCore 0x32a61819 <redacted> + 44
7 UIKit 0x32ddfe53 <redacted> + 86
8 CameraTest 0x000923b5 __35-[ViewController blockEnumeration:]_block_invoke + 184
9 CoreFoundation 0x305aa821 <redacted> + 92
10 libdispatch.dylib 0x3b3308eb <redacted> + 134
11 libdispatch.dylib 0x3b32fd71 <redacted> + 220
12 libdispatch.dylib 0x3b32ff59 <redacted> + 56
13 libsystem_pthread.dylib 0x3b46adbf _pthread_wqthread + 298
14 libsystem_pthread.dylib 0x3b46ac84 start_wqthread + 8
Fixing these 'uncommited CATransactions' by forcing them to run on the main thread fixed the black camera issues.
I was able to fix it by removing Option: NSEnumerationConcurrent from enumeration.
The sample app which could constantly reproduce the problem can be downloaded here
Hope the sample app could give some insight and the work around for the issue.
I had faced this issue in my app. Though I never found out the what the issue was, I rewrote my code to define a property of UIIMagePickerController type and initialize it once in the getter. Used this property to initialize the camera view :
getter:
-(UIImagePickerController *) imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc] init];
_imagePicker.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else{
_imagePicker.sourceType =UIImagePickerControllerSourceTypePhotoLibrary;
}
}
return _imagePicker;
}
- (IBAction)addNewImage:(id)sender{
if (self.imagePicker)
{
[self presentViewController:self.imagePicker animated:YES completion:^{}];
}
}
For some reason this got rid of the issue with preview sometimes showing a black screen
In ios7, you should set mainWindow.rootViewController = a class has kind is UIViewController. It's work for me.
If rootViewController is other, ex: UITabbarController, UINavigationController..., the black screen of camera will appear.

iPhone: SIGSEGV occurs seemingly randomly (ViewDidLoad, setFont, etc.) on device, never in simulator

First, thanks in advance for taking the time to read through this. I have been searching for an answer to this issue for a few days but I cannot seem to find what I am looking for. I know that SIGSEGV errors (or EXEC_BAD_ACCESS faults) are usually caused by memory management issues but after hours of looking at the code, I can't seem to find an error. The static analyzer hasn't found anything either.
As the title says, this error only occurs on the device (never in the simulator) and doesn't happen every time the given view loads. Obviously this means that I can't use NSZombie to debug what is going wrong.
Let's start with the crash dump log:
0 myApp 0x00036659 +[TFCrashHandler backtrace] + 428
1 myApp 0x00036a6f TFSignalHandler + 54
2 libsystem_c.dylib 0x32f48539 _sigtramp + 48
3 UIKit 0x365701df -[UIView(Rendering) setNeedsDisplay] + 86
4 UIKit 0x36598269 -[UILabel setFont:] + 232
5 myApp 0x000190eb +[BruUISettings applyLabelDetailStyle:] (BruUISettings.m:130)
6 myApp 0x0001aa57 -[ActiveChallengeViewController viewDidLoad] (ActiveChallengeViewController.m:115)
7 UIKit 0x365a57ff -[UIViewController view] + 166
8 UIKit 0x365b1c39 -[UIViewController contentScrollView] + 24
9 UIKit 0x365b1aa9 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 36
10 UIKit 0x365b198f -[UINavigationController _layoutViewController:] + 34
11 UIKit 0x365b115b -[UINavigationController _startTransition:fromViewController:toViewController:] + 318
12 UIKit 0x365b0f53 -[UINavigationController _startDeferredTransitionIfNeeded] + 250
13 UIKit 0x365a5673 -[UINavigationController pushViewController:transition:forceImmediate:] + 806
14 UIKit 0x365a5349 -[UINavigationController pushViewController:animated:] + 36
15 myApp 0x00015dc7 -[ChallengesHomeViewController tableView:didSelectRowAtIndexPath:] (ChallengesHomeViewController.m:325)
16 UIKit 0x3661f565 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 944
17 UIKit 0x36697ce7 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 158
18 Foundation 0x31f7a943 __NSFireDelayedPerform + 414
19 CoreFoundation 0x34ab1a63 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
20 CoreFoundation 0x34ab16c9 __CFRunLoopDoTimer + 364
21 CoreFoundation 0x34ab029f __CFRunLoopRun + 1206
22 CoreFoundation 0x34a334dd CFRunLoopRunSpecific + 300
23 CoreFoundation 0x34a333a5 CFRunLoopRunInMode + 104
24 GraphicsServices 0x351a7fed GSEventRunModal + 156
25 UIKit 0x3659a743 UIApplicationMain + 1090
26 myApp 0x000026c5 main (main.m:13)
27 myApp 0x0000265c start + 52
Note, I am using TestFlight from testflightapp.com and it is there exception handler at the top of the stack.
Here is the code that is creating and pushing the view controller in question:
CDAcceptedChallenge *challengeAtIndex = [self.activeChallenges objectAtIndex:[indexPath row]];
ActiveChallengeViewController *view = [[ActiveChallengeViewController alloc] initWithNibName:#"ActiveChallengeViewController"
bundle:nil
activeChallenge:challengeAtIndex];
view.leaveChallengeTarget = self;
[self.navigationController pushViewController:view animated:YES];
[view release];
This code is running inside of a didSelectRowAtIndex method, if that matters at all. This view controller has a bunch of member variables and IBOutlets which reference objects in the nib but here are the ones that correlate to the object mentioned in this error:
in .h:
UILabel *helpLabel;
...
#property (nonatomic, retain) IBOutlet UILabel *helpLabel;
in .m:
#synthesize helpLabel;
I am positive that helpLabel is bound to the correct object in the nib because it does get the correct styling when this doesn't blow up. Next, here is the init method for this view controller:
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.activeChallenge = inActiveChallenge;
}
return self;
Here is the viewDidLoad method where we will sometimes see the crash (bolded). Note, there is a lot going on here but nothing touches the self.helpLabel which is what eventually triggers the crash.
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:FALSE];
self.navigationItem.title = #"Details";
// overlay disclosure creation
self.overlayDisclosure = [CustomColoredDisclosureIndicator accessoryWithColor:self.challengeNameLabel.textColor];
self.overlayDisclosure.highlightedColor = [UIColor whiteColor];
[self.overlayDisclosure addTarget:self action:#selector(overlayViewButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.overlayDisclosure];
[[BruNotificationManager instance] registerForTabUpdated:[[[BruCallback alloc] initWithTarget:self
andCallback:#selector(tabUpdated:)] autorelease]];
[[BruNotificationManager instance] registerForActiveChallengesUpdated:[BruCallback buildFromObject:self
andCallback:#selector(challengesUpdatedLocally)]];
[[BruNotificationManager instance] registerForEarnedRewardsUpdated:[BruCallback buildFromObject:self
andCallback:#selector(rewardsUpdatedLocally:)]];
[super refreshEarnedRewardsForChallenge:self.activeChallenge.challenge.identifier];
[super refreshTabForChallenge:self.activeChallenge.challenge.identifier];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addBeer)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
// Request that the object download its image
BruCallback *imageCallback = [BruCallback buildFromObject:self andCallback:#selector(imageRequestCompleted:withData:)];
self.challengeImageView.image = [self.activeChallenge.challenge retrieveImage:self.bruConnection withCallback:imageCallback];
// Create our help label
**[BruUISettings applyLabelDetailStyle:self.helpLabel];**
self.helpLabel.textColor = AccentSecondaryColor;
self.overlayView.alpha = [BruUISettings standardOverlayViewAlpha];
[BruUISettings applyTableStyle:self.rewardsTable];
[BruUISettings applyScrollViewStyle:self.scrollView];
self.needToUpdateTab = YES;
self.needToUpdateRewards = YES;
self.needToUpdateChallenge = NO;
Here is a trimmed down version of the viewDidUnload method, though I don't see why it would matter in this case:
...
self.helpLabel = nil;
...
[super viewDidUnload];
Finally, my [BruUISettings applyLabelDetailStyle] is a method that applies a centralized style to my label. There are a bunch of places in my code that use this function so that I can change all of the styles for those labels by just changing the one function.
+ (void) applyLabelDetailStyle:(UILabel *)inLabel
{
inLabel.font = [UIFont fontWithName:#"Helvetica Neue" size:12.0];
inLabel.textColor = [UIColor darkGrayColor];
inLabel.backgroundColor = [UIColor clearColor];
}
Any thoughts as to what could be happening here would be greatly appreciated. Thanks again.
After a lot of debugging I found that this was actually due to a memory corruption being caused by the QSStrings library which I was using to generate base64 encoded strings. The crashes seemed to happen randomly but only after this library was invoked. When I switched to a different MD5 library, the issue went away. If you are using this library, I would suggest finding a new one to do base64 encoding. I moved to the one found here: http://www.cocoadev.com/index.pl?BaseSixtyFour
I think the problem happens because you have something wrong in your view that owns your label (view of your ActiveChallengeViewController).
When you set the font of your label, that invokes the setNeedsDisplay of your parent view and because something is wrong, setNeedsDisplay crashs.
Your line :
self.challengeImageView.image = [self.activeChallenge.challenge retrieveImage:self.bruConnection withCallback:imageCallback];
Is it a synchronous connection to retrieve the image ?
Maybe the problem happen here when sometimes the image isn't retrieved from your connection and so the image property of your image view is bad.
But i am not sure because setNeedsDisplay doesn't directly invoke the redraw of the view so i don't know if the debugger catches the error just the after setNeedsDisplay call.
Edit :
I think this answer is bad, if image is not ok, the crash must happen when the imageView image property retains the image but i let the answer in the case of it could help you to point to the real problem.

App crashes when i attempt to select a row while table was loading

I define my array in my AppDelegate.h like this:
NSMutableArray *myWishesArray;
.
.
#property (nonatomic, retain) NSMutableArray *myWishesArray;
In AppDelegate.m, i allocate its object like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myWishesArray = [[NSMutableArray alloc] init];
.
.
return YES;
}
Suppose i have a function "Add Data to array", like this:
-(void)addDataToArray
{
NSMutableArray *tempArray = //Gets data from a web service
if ([tempArray count] > 0) {
[objAppDelegate.myWishesArray addObjectsFromArray:tempArray];
[self.myWishesTableView reloadData];
}
}
In viewDidLoad of MyViewController.m, I load the first set of 8 records into my array:
- (void)viewDidLoad {
[self addDataToArray]; //fetches page number 1 of the data to be fetched
}
In scrollViewDidEndDragging of MyViewController.m, i add next set of 8 records and use the same above mentioned code to add it in the objAppDelegate.myWishesArray:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
currentPageNumber++;
[self addDataToArray]; //fetches data for next page number
}
-(void)viewWillAppear:(BOOL)animated
{
[self.myWishesTableView reloadData];
}
This is my cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *myArrayObject = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
}
Every time i try to click a row of the table which was visible in my table view, but was just at the end of being loaded, my app gets crashed with the following exception. It may be initial loading or loading more rows as a result of scrolling down the table view. Please keep in mind that when i give the table view enough time to settle and the motion stops and data is fully loaded, then i dont face any exception on clicking the loaded rows.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x013a8be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x014fd5c2 objc_exception_throw + 47
2 CoreFoundation 0x0139e80c -[__NSArrayI objectAtIndex:] + 236
3 WishHaHa 0x00004e1a -[AsyncImageView image] + 66
4 UIKit 0x0044e56b -[UIImageView setBackgroundColor:] + 101
5 UIKit 0x00549448 -[UITableViewCell _setOpaque:forSubview:] + 953
6 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
7 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
8 UIKit 0x0054472d -[UITableViewCell(UITableViewCellStatic) _updateAndCacheBackgroundColorForHighlightIgnoringSelection:] + 117
9 UIKit 0x0054c12a -[UITableViewCell showSelectedBackgroundView:animated:] + 1435
10 UIKit 0x00548ce3 -[UITableViewCell setHighlighted:animated:] + 231
11 UIKit 0x003fbd3b -[UITableView highlightRowAtIndexPath:animated:scrollPosition:] + 756
12 UIKit 0x003f78d8 -[UITableView touchesBegan:withEvent:] + 1349
13 UIKit 0x004512b8 forwardMethod2 + 92
14 UIKit 0x0054cc15 -[UITableViewCell touchesBegan:withEvent:] + 319
15 UIKit 0x004512b8 forwardMethod2 + 92
16 UIKit 0x00610987 _UIGestureRecognizerSortAndSendDelayedTouches + 3609
17 UIKit 0x006110fc _UIGestureRecognizerUpdateObserver + 927
18 CoreFoundation 0x01389fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
19 CoreFoundation 0x0131f0e7 __CFRunLoopDoObservers + 295
20 CoreFoundation 0x012e7bd7 __CFRunLoopRun + 1575
21 CoreFoundation 0x012e7240 CFRunLoopRunSpecific + 208
22 CoreFoundation 0x012e7161 CFRunLoopRunInMode + 97
23 GraphicsServices 0x01a9d268 GSEventRunModal + 217
24 GraphicsServices 0x01a9d32d GSEventRun + 115
25 UIKit 0x0039442e UIApplicationMain + 1160
26 WishHaHa 0x00002a5c main + 102
27 WishHaHa 0x000029ed start + 53
)
terminate called after throwing an instance of 'NSException'
I have done a lot of research on my problem and found that possible causes of NSRangeException may be:
numberOfRowsInSection:(NSInteger)section; method of the UITableView's
data source is delivering wrong values.
retain should be called on the array.
Whenever you modify the underlying data for a table view you need to
update the changes by either calling -[UITableView reloadData]; or
the beginUpdates and endUpdates methods then adding or removing the
correct index paths.
I dont think that my code has first issue. If there is second issue, then where should i make the call to retain myWishesArray? If there is third issue with my code, then how should i proceed to change my code?
Please let me know where i am doing anything wrong. I am stuck on this issue since really long.
Thanks
Edit:
After thorough investigation of the code, i have found the point which is causing this error. I am asynchronously downloading the images in cells of my table view, using the asyncimageview class. Let me paste some code here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomWishCell";
CustomWishCell *cell = (CustomWishCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomWishCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomWishCell *) currentObject;
break;
}
}
}
else
{
AsyncImageView* oldImage = (AsyncImageView*)[cell.contentView viewWithTag:999];
[oldImage removeFromSuperview];
}
if (indexPath.row<[objAppDelegate.myWishesArray count]) {
Wish *objWish = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
NSString *test = objWish.facebookUserId;
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
cell.wishLabel.attributedText = [self.myEngine makeWisherNameAndContents:objWish.firstName lastName:objWish.lastName wishContents:objWish.contents];
}
return cell;
}
Now, myEngine contains the definitioin:
-(void)loadAsynchronousImageURLInView:(NSString*)imageUrl imageView:(UIView*)targetView
{
CGRect frame;
frame.size.width=45;
frame.size.height=45;
frame.origin.x=0;
frame.origin.y=0;
if (imageUrl != (id)[NSNull null] )
{
AsyncImageView* asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
asyncImage.tag = 999;
NSURL *url = [NSURL URLWithString:imageUrl];
[asyncImage loadImageFromURL:url];
[targetView addSubview:asyncImage];
}
}
And the AsyncImageView class loads the image using NSURLConnection class.
Please note that the app works all ok when i comment this line defined in cellForRowAtIndexPath method:
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
It does not crash when i click on any row that was loading. Please let me know how should i change my logic. I am not allowed to load the images synchronously, or show any indicator while images are downloading.
Your array with which you are loading your tableview is either not getting filled or is getting released somewhere before you tap on the tableView.
Please add the code where you release your array and Also please make sure that you are synthesizing your array in AppDelegate.
I think there is some issue with the array and not the tableView as array is getting empty.
I hope this helps.
It sounds to me as if your addDataToArray method does not manage to retrieve the data and fill the myWishesArray array before the click is handled.
Are you retrieving the data from the web service asynchronously?
Is there any way to retrieve all the data at once instead of retrieving it by sections?

Help me ...Terminating app due to uncaught exception 'NSRangeException',

- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self selector:#selector(loadImage) object:nil];
[queue addOperation:operation];
[operation release];
NSMutableArray *_array = [[NSMutableArray alloc] initWithCapacity:10000];
self.array = _array;
[_array release];
}
- (void)loadImage
{
for(int i = 0;i < [appDelegate.ArrParseData count]; i++ )
{
NSLog(#" count %i",i);
// Configure the cell...
XMLTags *xmltag = [appDelegate.ArrParseData objectAtIndex:i];
NSString *Img_id, *Img_name, *DynamicImgUrl;
Img_id = xmltag.equip_id;
Img_name = xmltag.image;
DynamicImgUrl = [NSString stringWithFormat:#"http://testetete.com/pics/equipment/%#/%#",Img_id, Img_name];
NSURL *ImageUrl = [NSURL URLWithString:DynamicImgUrl];
NSLog(#" ccxvount %#",ImageUrl);
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:ImageUrl]];
NSLog(#" ccxvount %i",i);
[self.array addObject:image];
NSLog(#" ccxvount %i",i);
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UIImageView *top_img = [[UIImageView alloc] initWithFrame:CGRectMake(10, 25, 75, 80)];
CGRect rect = top_img.frame;
rect.size.height = 60;
rect.size.width = 60;
top_img.frame = rect;
// the imageView holds the image myImg
top_img.image = [self.array objectAtIndex:indexPath.row];
//cell.imageView.image=image;
[cell.contentView addSubview:top_img];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [appDelegate.ArrParseData count];
}
when i excecute the above code my application gets crashes with the following error..
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x026cc919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0281a5de objc_exception_throw + 47
2 CoreFoundation 0x026c2465 -[__NSArrayM objectAtIndex:] + 261
3 AgSearch 0x00006f80 -[EquipmentViewController tableView:cellForRowAtIndexPath:] + 752
4 UIKit 0x00345a3f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619
5 UIKit 0x0033bad2 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
6 UIKit 0x0035040c -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
7 UIKit 0x003484bc -[UITableView layoutSubviews] + 242
8 QuartzCore 0x024620d5 -[CALayer layoutSublayers] + 177
9 QuartzCore 0x02461e05 CALayerLayoutIfNeeded + 220
10 QuartzCore 0x0246164c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302
11 QuartzCore 0x024612b0 _ZN2CA11Transaction6commitEv + 292
12 QuartzCore 0x02468f5b _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
13 CoreFoundation 0x026add1b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
14 CoreFoundation 0x02642987 __CFRunLoopDoObservers + 295
15 CoreFoundation 0x0260bc17 __CFRunLoopRun + 1575
16 CoreFoundation 0x0260b280 CFRunLoopRunSpecific + 208
17 CoreFoundation 0x0260b1a1 CFRunLoopRunInMode + 97
18 GraphicsServices 0x02f312c8 GSEventRunModal + 217
19 GraphicsServices 0x02f3138d GSEventRun + 115
20 UIKit 0x002e3b58 UIApplicationMain + 1160
21 AgSearch 0x0000206c main + 102
22 AgSearch 0x00001ffd start + 53
23 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Any help would be greatly appreciated....
Thanks for nay help
does the array has any data when you show the table? if you give a default number of cells that is bigger than 0 and there is no data in the array..then you will receive the error you described.
'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
EDIT:
in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [appDelegate.ArrParseData count];
}
you shouldn't return the number of elements from the appDelegate.ArrParseData because if that array is filled with data then you will receive a number X bigger than 0.
in the cellForRowAtIndexPath you ask for information at index X but self.array is not filled yet with data because you call the loadImage method async.
You should return [self.array count]; in the numberOfRowsInSection method.
I don't think you are showing all the code you need to show - the trace shows the exception happens some time in cellForRowAtIndexPath. Looks like you are accessing an array that contains nothing - are you completely sure the array has been loaded by the time you try to use it?
Likely you know how many cells there will be and you report that correctly through numberOfRowsInSection, but you haven't populated the array by the time it is required. You need to so something like display placeholders until the load is finished, leave the images nil (empty) until ready, make the data load/view appearance sequential, get the load happening in the background earlier or something like that.
Your number of rows method is accessing a different count array from the one which contains your image, isn't it?
If you executed this code in no concurrent way, you wouldn't have this error. The problem comes when the thread who has to fill in your images array is slower than the main one.
So your best solution would be to check the images array size before accessing it and if you want you could send a reloadRowsAtIndexPaths: withRowAnimation: message to your tableView every time that you get a new image. This would give you a nice loading effect.
I hope I've been clear enough.
See you!
maybe someone make such stupid mistake like me in:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
and try to do something like this:SomeObject = [SomeContainer objectAtIndex:indexPath]; Or even try to be clever with cast: SomeObject = [SomeContainer objectAtIndex:(int)indexPath]; WRONG
no way...JUST
remember to get index you have to call indexPath.row!!!!!

Iphone Core Data crashing on Save

I'm currently writing an Iphone application using Core Data and I get a EXC_BAD_ACCESS error during the [managedObjectContext save:&&error] code line. This crash only happens after I modify certain fields. More specifically my entity has two string fields (out of about 10 fields), that get their values from a the return of a modal view controller (like a text editor). The crash also only happens after these fields are edited, the first time I put a value in it works fine.
The reason I have string with format constructors with just strings is because I was trying to copy construct... not sure if that happens automatically? Thought maybe retain/release messages from those strings (those two are from the modal view controller), were getting released on dismissal of the modal view controller or something. Guess not though because it still doesn't work.
Here's the code section that is crashing:
[EDITED]
- (void)actionSheet:(UIActionSheet *)modalView clickedButtonAtIndex: (NSInteger)buttonIndex
switch(buttonIndex) {
case 0: {
if(message == nil) {
message = [NSEntityDescription insertNewObjectForEntityForName:#"MailMessage" inManagedObjectContext:self.managedObjectContext];
}
message.toString = txtTo.text;
message.fromString = txtFrom.text;
message.subjectString = txtSubject.text;
message.backgroundColor = [NSNumber numberWithInt:[bgColor intValue]];
message.textArray = [NSString stringWithFormat:#"%#", stringTextArray];
message.htmlString = [NSString stringWithFormat:#"%#", stringHTML];
message.timeStamp = [NSDate date];
message.statusCode = [NSNumber numberWithInt:0];
NSError *error = nil;
if (![message.managedObjectContext save:&error]) {
abort();
}
break;
}
case 1: {
break;
}
}
if(buttonIndex != modalView.cancelButtonIndex) {
[webViewBody loadHTMLString:#"<html><head></head><body></body></html>" baseURL:[NSURL URLWithString:#""]];
[self.navigationController popToRootViewControllerAnimated:YES];
}
}
And here's the crash log:
Exception Type: EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000015
Crashed Thread: 0
Thread 0 Crashed:
0 libobjc.A.dylib 0x30011940 objc_msgSend + 20
1 CoreData 0x367f7d3e -[NSKnownKeysDictionary1 dealloc] + 82
2 CoreData 0x367f7cda -[NSKnownKeysDictionary1 release] + 34
3 CoreData 0x3687eec4 -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] + 40
4 CoreData 0x36821030 -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] + 16
5 CoreData 0x368205f2 -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] + 958
6 CoreData 0x368133bc -[NSManagedObjectContext save:] + 412
7 Decome 0x0001fdd6 -[CreateMessageViewController actionSheet:clickedButtonAtIndex:] (CreateMessageViewController.m:163)
8 UIKit 0x30a6cbd8 -[UIActionSheet(Private) _buttonClicked:] + 256
9 CoreFoundation 0x30256dd4 -[NSObject performSelector:withObject:withObject:] + 20
10 UIKit 0x3096e0d0 -[UIApplication sendAction:to:from:forEvent:] + 128
11 UIKit 0x3096e038 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
12 UIKit 0x3096e000 -[UIControl sendAction:to:forEvent:] + 44
13 UIKit 0x3096dc58 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 528
14 UIKit 0x309a6e9c -[UIControl touchesEnded:withEvent:] + 452
15 UIKit 0x309a60d4 -[UIWindow _sendTouchesForEvent:] + 520
16 UIKit 0x309a5464 -[UIWindow sendEvent:] + 108
17 UIKit 0x30936e3c -[UIApplication sendEvent:] + 400
Any help is appreciated, Thanks.
UPDATE: Also, even though the program crashes, when I open it back up it the data has saved correctly. So the EXC_BAD_ACCESS must happen after the save has gotten at least far enough to store in the persistent store i think.
If I comment out the save line, the code runs fine now. But it doesn't save after i close and exit. If I run the save line in my Root View Controllers willAppear function, it throws the same EXC_BAD_ACCESS error. The console doesn't say anything other than EXC_BAD_ACCESS
if I do a backtrace I get :
#0 0x30011940 in objc_msgSend ()
#1 0x367f7d44 in -[NSKnownKeysDictionary1 dealloc] ()
#2 0x367f7ce0 in -[NSKnownKeysDictionary1 release] ()
#3 0x3687eeca in -[NSManagedObject(_NSInternalMethods) _setOriginalSnapshot__:] ()
#4 0x36821036 in -[NSManagedObjectContext(_NSInternalAdditions) _clearOriginalSnapshotAndInitializeRec:] ()
#5 0x368205f8 in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] ()
#6 0x368133c2 in -[NSManagedObjectContext save:] ()
#7 0x0000314e in -[RootViewController viewWillAppear:] (self=0x11b560, _cmd=0x3014ecac, animated=1 '\001') at /Users/inckbmj/Desktop/iphone/Decome/Classes/RootViewController.m:85
Sorry the code wasn't properly formatted before. When this view controller gets created if it is not a new "message" it is passed a message object obtained from a fetchedResultsController like so:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
MailMessage *aMessage = (MailMessage *)[fetchedResultsController objectAtIndexPath:indexPath];
[messageView loadMessage:aMessage viewOnly:NO usingTemplate:NO];
messageView.managedObjectContext = self.managedObjectContext;
[self.navigationController pushViewController:messageView animated:YES];
}
(the first set of code is from the MessageViewController.m file which is the class that messsageView is)
It only crashes if I present my EditorViewController as a modal view and then return.
Even if I change the textArray and htmlString lines (which are the only things the modal view affects) to:
message.textArray = #"HELLO";
message.htmlString = #"HELLO";
it still crashes. If I comment both lines out however it doesn't crash.
So it seems like it crashes if I present a modal view and then try to edit either the textArray or htmlString fields of my NSOManagedObject...
Here is where i present the view:
- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event {
if(!viewOnly) {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: txtTo];
location = [touch locationInView: webViewBody];
if(CGRectContainsPoint(webViewBody.bounds, location)) {
[editor loadTextArrayString:stringTextArray];
[self presentModalViewController:editor animated:YES];
}
}
}
and where i dismiss it:
-(void)returnWithTextArray:(NSString *)arrayString HTML:(NSString *)html bgColor:(NSNumber *)numColor {
[self dismissModalViewControllerAnimated:YES];
self.stringTextArray = [NSString stringWithFormat:#"%#", arrayString];
self.stringHTML = [NSString stringWithFormat:#"%#", html];
self.bgColor = [NSNumber numberWithInt:[numColor intValue]];
[webViewBody loadHTMLString:self.stringHTML baseURL:[NSURL URLWithString:#""]];
}
You are only guaranteed to retain access to a managed object from the context as long as a change is pending to that object (insert, update, delete). As soon as you make a call to save:, you can lose your reference to the managed object.
While you stopped getting the error when you set setRetainsRegisteredObjects:YES, you may have introduced a memory management issue, as you are setting the managed object's lifetime to be dependent on the lifetime of the managed object context. If you're passing your context around throughout your app, this could get rather large if you have a large object hierarchy.
You can read more in the Apple docs here: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/MO_Lifecycle.html
Solved the problem though I'm not sure I'm addressing the actual root cause. The error was eliminated when I added this line:
[managedObjectContext setRetainsRegisteredObjects:YES];
To where I create the managedObjectContext. So I guess it had to do with retain counts. I'm guessing that maybe instance variables get released partially or temporarily or something when modal views are presented? I don't know. In any case, this error was eliminated the the program works fine now.
Just to help others having the same issue, and reinforcing Steff's response above, the likely cause of this error is that you are trying to release a NSManagedObject.
I have seen many funny behaviours with CoreData on iPhone that were solved by resetting content and settings in the iPhone simulator.
I know this is an oldie but I had the same issue so thought I'd add my tuppence as to how I solved the issue, mine was caused by manually releasing the managed object within the modal view, I removed the release calls and everything is working fine :) according to the docs you shouldn't manually try and release managed objects anyway as the context will look after all of that. That's my experience anyway, search through your code for over-released values.
You must set the FRC cache to nil
I have solved a similar problem by making sure that the object is fetched, so for the example above:
if ( message == nil ) {
message = [NSEntityDescription insertNewObjectForEntityForName:#"MailMessage" inManagedObjectContext:self.managedObjectContext];
} else {
NSError *error = nil;
message = (MailMessage *)[managedObjectContext existingObjectWithID:[message objectID] error:&error];
}