Ensembles crash in CDERebaser.m - ensembles

In Ensembles, I'm getting a crash at this line in CDERebaser.m in the method "rebaseWithCompletion":
BOOL passedChecks = [revisionManager checkRebasingPrerequisitesForEvents:eventsToMerge error:&error];
The crash is EXC_BAD_ACCESS.
I've had Ensembles working in production on the store for a few months with no issue at all until now. This crash just started randomly occurring. No updates to the app were made.
Any ideas?
** UPDATE **
Stepping through it, it seems to fail in this conditional statement in CDERevisionManager.m:
if (![self checkContinuityOfStoreModificationEvents:eventsWithBaseline]) {
methodError = [NSError errorWithDomain:CDEErrorDomain code:CDEErrorCodeDiscontinuousRevisions userInfo:nil];
result = NO;
return;
}

Related

No code execution when the method sendAsynchronousRequest of NSRLConnection fails

I've implemented this operation:
[NSURLConnection sendAsynchronousRequest:theRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError) {
NSLog(#"Error %# | contaShow %i",connectionError.description,_contaShow);
//OPERATIONS in case of error
} else {
//OPERATIONS in case of success
Sometime, if occurs a connection error (ex. lost connection) I want execute the code inside the if block.
With debug I can see that the code lines are called, but aren't executed!!!
Somebody can tell me why?!?
Thanks...
If the connection returns an error code (e.g. 404), you'll likely go into the success case, because you need to also check the value of ((NSHTTPURLResponse *)response).statusCode to make sure it is 200.
Beyond that, make sure you're using a debug build. Otherwise, the debugger may lie to you about what lines of code are executing.

NSFileManager enumeratorAtURL doesn't work properly on XCode 6 / iOS 8

I'm on Mavericks.
I'm using the simulator.
It appears that NSFileManager URL based methods don't work properly on XCode 6 / iOS 8.
In my code sample at bottom, the path being searched in 'directoryToScan' is ...
/Users/xxxx/Library/Developer/CoreSimulator/Devices/A092C58C-1A43-4AF3-A9B1-109D7BA27F8D/data/Containers/Data/Application/41232C14-CF90-4E5C-72A7-8FF464FE7C32/Documents
In the code at bottom, even though I have files at the path I'm providing, when my code reaches the "for in" enumerator, it jumps right over the "for in" block to the end of it, and continues at the next line, and I get NO ERROR message from the block in the errorHandler.
I also tried a while clause, and that did the same.
Also, I tried two other techniques...
// THIS DOES NOT WORK
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:directoryToScan includingPropertiesForKeys:nil options:NSDirectoryEnumerationSkipsHiddenFiles error:&theError];
// THIS DOES WORK
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentDirectory error:&theError];
So it appears there's a problem with NSURL's in iOS 8.
Any idea what's going on? I would think if there were a permission issue, I would have seen an error in my handler.
NSURL *directoryToScan = [NSURL fileURLWithPath:documentDirectory];
NSDirectoryEnumerator *dirEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:directoryToScan
includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLIsDirectoryKey, nil]
options:NSDirectoryEnumerationSkipsHiddenFiles | NSDirectoryEnumerationSkipsSubdirectoryDescendants | NSDirectoryEnumerationSkipsPackageDescendants
errorHandler:^(NSURL *url, NSError *error){
NSLog(#"Error occurred at url %#",url);
NSLog(#"Error message is %#",error);
return YES;}];
for (NSURL *theURL in dirEnumerator)
{
// Work with the files found by dirEnumerator.
// This whole block is being skipped over.
}
If you are still interesting in investigating the issue can You please provide the code for setting directoryToScan and documentDirectory? Have you tried to print both values during debug to ensure they both address same directory? In Xcode 6.1?
In Xcode 6.1 both for (NSURL *theURL in dirEnumerator) and for (NSURL* theURL = [dirEnumerator nextObject]) work fine for me.

AV Foundation: Difference between currentItem being ready to play, and -[AVPlayer readyForDisplay] property?

I'm running into a weird situation with my video player, the core code of which hasn't changed much from what worked in an earlier app I made. Here's the problem: I'm inserting a "_loadingLayer" (a CATextLayer that says the video is loading), and then observing the AVPlayer's currentItem's status property to figure out when to remove the "_loadingLayer" and replace it with my actual "_playerLayer". Here's my KVO code for that:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ((object == _playerLayer) && (_playerLayer.player.currentItem.status == AVPlayerItemStatusReadyToPlay)) {
[CATransaction setAnimationDuration:1.8];
_loadingLayer.opaque = NO;
if (_playerLayer.readyForDisplay) {
NSLog(#"Should be ready now.");
}
[self addPlayerLayerToLayerTree];
}
}
My problem is that the video is starting, but only the audio is playing -- the layer stays black. When I inserted the NSLog statement above, I found out why: Apparently although the currentItem's status is "AVPlayerItemStatusReadyToPlay", the player layer isn't actually readyForDisplay. This makes no sense to me -- it seems counterintuitive. Can someone please give me some guidance on this?
I was able to verify that _playerLayer is being added to the layer tree by setting its background color to red.
One other weird thing that I think might be related.... I've been seeing these messages in the debugger console:
PSsetwindowlevel, error setting window level (1000)
CGSSetIgnoresCycle: error 1000 setting or clearing window tags
Thanks in advance. This is a crosspost from the Apple Dev Forums.
We had a similar problem and traced it to what I believe is a bug in iOS 5.1 (and maybe earlier versions). It is fixed in iOS 6.0. Since I couldn't find a solution to this anywhere, I'm writing a long writeup for future people that have this problem.
If the AVPlayerItem reports a status of AVPlayerStatusReadyToPlay before the AVPlayerLayer has been obtained then the AVPlayer will never report that it is readyForDisplay.
So when you do:
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
make sure that it's followed with:
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
and that you don't have much if any code in between the two.
I built a test rig to make it work 100% of the time or fail 100% of the time. Note that it can be tricky to see what's going on in your actual app since you will have different load times on the video and that will affect how quickly the playerItem reports AVPlayerStatusReadyToPlay.
If you want to test in your app, put this into a simple view. The below will not work (i.e. you'll hear audio but not see video) on iOS 5.1. If you switch loadPlayerLayer to instead be invoked at the end of loadPlayer, it will always work.
A follow on for future readers: A couple of player events can switch up this order and make you think it's working. They're red herrings though since they're inadvertently reversing the load order such that playerLayer is grabbed before AVStatusReadyToPlay. The events are: seeking the video, going to the home screen and then reactivating the app, the player switching to a different video/audio track inside an HLS video. These actions trigger AVStatusReadyToPlay again and thus make the playerLayer happen before AVStatusReadyToPlay.
Here's the test harness that uses Apple's test HLS video:
-(void)loadPlayer
{
NSLog(#"loadPlayer invoked");
NSURL *url = [NSURL URLWithString:#"https://devimages.apple.com.edgekey.net/resources/http-streaming/examples/bipbop_4x3/bipbop_4x3_variant.m3u8"];
self.playerItem = [AVPlayerItem playerItemWithURL:url];
[self.playerItem addObserver:self forKeyPath:#"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerContext];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
}
-(void)loadPlayerLayer
{
NSLog(#"starting player layer");
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
[self.playerLayer addObserver:self forKeyPath:#"readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:&kPlayerLayerContext];
[self.playerLayer setFrame:[[self view] bounds]];
[[[self view] layer] addSublayer:self.playerLayer];
}
-(void)observeValueForKeyPath:(NSString*)path ofObject:(id)object change:(NSDictionary*)change context:(void*) context
{
if(context == &kPlayerContext){
if([self.player status] == AVPlayerStatusReadyToPlay){
NSLog(#"Player is ready to play");
//Robert: Never works if after AVPlayerItem reports AVPlayerStatusReadyToPlay
if(!self.startedPlayerLayer){
self.startedPlayerLayer = YES;
[self loadPlayerLayer];
}
}
}
if(context == &kPlayerLayerContext){
if([self.playerLayer isReadyForDisplay] == YES){
NSLog(#"PlayerLayer says it's ready to display now");
[self playTheVideoIfReady];
}
}
}

Iphone app wont run after upgrading to iOS 4.2

After installing Xcode 3.2.5 iOS 4.2 an app that was perfectly working stopped working. I have seen that this has happened to others but cant understand how to solve it.
My questions are:
1. How can I know where it is crashing?
2. What can I do to better debug and pinpoint the problem.
Here is the call stack.
Tommy thanks for the answer. I have build and run and suggested but when it crashes it does not shows where it crashed. Also I added a breakpoint inside the method but it does not stops there. Any further ideas? Here is the code snippet.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
ApplicationData *appdata = [ApplicationData sharedInstance];
if(appdata.currentCategoryIndex >= 0) {
Category *category = [appdata.categoryList objectAtIndex:appdata.currentCategoryIndex];
if(category.records) {
[lab_norecords setHidden:YES];
} else {
[lab_norecords setHidden:NO];
return 0;
}
return [category.records count];
}
return 0;
}
Now I am getting this error:
I believe the source of the problem is here in the same subCategoryView:
- (id)init {
if([[NSBundle mainBundle] loadNibNamed:#"SubCategoryView" owner:self options:nil]) {
//if(self = [super initWit])
cellowner = [[TableCellOwner alloc] init];
[listTableView setBackgroundColor:[UIColor clearColor]];
[listTableView setSeparatorColor:[UIColor whiteColor]];
[listTableView initialize];
}
return self;
}
From the trace you've got, check out the second column. The most recent thing in your application was a call to SubCategoryView numberOfSectionsInTableView:, in the fourth row (the one numbered '3'). The triggered exception was NSRangeException, where you attempted to retrieved object 4294967295 from an array with 22 objects in it. 4294967295 is how -1 looks if you cast a signed 32bit number to an unsigned number, so for some reason you're doing something like:
NSInteger variable = -1;
[array objectAtIndex:variable];
Somewhere within SubCategoryView's numberOfSectionsInTableView. Best immediate guess: some change between 4.1 and 4.2 is causing whatever method you use to populate the table to come up with the wrong results.
To advance from here, make sure you're doing a debug build and launch with command+y (or go to Build, Build and Run - Breakpoints On). When your program crashes this time the debugging window should appear, showing you exactly the line your program throws an exception at and allowing you to inspect the state of all your program variables at that point. The debugger will also allow you to place breakpoints, step through your program one line at a time and all the other usual things.

Can I trust Cocoa APIs not to fail silently, or do I have to defensively check everything?

Coming from a Symbian background, I'm somewhat concerned about the seeming lack of error handling in Cocoa. Cocoa has many methods that, as far as I can see, have no error reporting and yet could fail.
Eg How come NSMutableString appendString has a void return type and doesn't throw exceptions (at least the documentation doesn't mention any)? Surely if I append a long enough string then theoretically I could run out of memory. Is it paranoid of me to check the length of the NSMutableString before and after appending to verify that the append worked?
My test is on Mac OS X and I imagine you're talking about the iPhone platform.
The thing is I fail to see how returning an error from the appendString method would help since the platform is at that point in such a state that it can't satisfy malloc requests for your process.
To get around the problem you can probably malloc your own address space and use this process managed memory as storage for your strings. I think Carbon's CFString (toll free bridged to NSString) allows you to use your own memory allocator.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [NSAutoreleasePool new];
NSMutableString * m = [NSMutableString stringWithCapacity:100000];
int i;
for(i=0;i<1000000;i++)
[m appendString:#"ABCDE..."]; //1400 characters long
[pool release];
}
cd:tmp diciu$ ./a.out
a.out(2216) malloc: *** mmap(size=1220067328) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
[..]
2009-08-13 16:45:44.163 a.out[2216:10b] *** Terminating app due to uncaught exception 'NSMallocException', reason: 'Out of memory. We suggest restarting the application. If you have an unsaved document, create a backup copy in Finder, then try to save.'
2009-08-13 16:45:44.165 a.out[2216:10b] Stack: (
2494541803,
2485014075,
2435399864,
2494157025,
2494172776,
2434276628
)
Trace/BPT trap
I modified diciu's code testing NSMutableString appendString to fail quicker and to try to catch any exceptions. Here is the core section:
NSMutableString * m = [[NSMutableString alloc] initWithCapacity:1000];
NSMutableString * n = [[NSMutableString alloc] initWithCapacity:1000];
#try {
[m appendString:#"1234567890"];
[n appendString:m];
int i;
for(i=0;i<100;i++) {
[m appendString:n];
[n appendString:m];
}
}
#catch (id exception) {
NSLog(#"!!Exception");
}
// #catch (NSException *exception) {
// NSLog(#"!!Exception: %#", [exception name]);
// }
#finally {
[m release];
[n release];
NSLog(#"Finally...");
}
I tested on various platforms:
Mac OS X 10.5.8 & Xcode 3.1.3 iPhone 3.0 Emulator: An exception thrown (NSException, with name NSMallocException). This is good news but strange since NSMallocException is supposedly obsolete.
iPhone 3.0.1: the app crashes.
The bad news is that for the iPhone it seems like there is no way to catch this error.
The good news is that there is no point defensively programming, since the whole application blows up anyway!
I hope someone has a better answer than this.

Resources