constraintWithItem crashes on simulator for iOS 7 - objective-c

I bounced into an opposite situation as the usual. On running my app in the simulator it crashes on the apparently harmless instruction:
topConstraint = [NSLayoutConstraint constraintWithItem:appendino attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.backStatus attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
while it works seamlessly on my 3.5'' iPhone. I have no 4'' iPhone to test it on, but the simulator also crashes when simulating the former format.
It does not report any message neither in the console nor in the device logs, but for a crash address, and it happens at the creation of the constraint rather than at its application.
libobjc.A.dylib`objc_exception_throw:
0x1cc388a: pushl %ebp
0x1cc388b: movl %esp, %ebp
0x1cc388d: pushl %ebx
0x1cc388e: pushl %edi
0x1cc388f: pushl %esi
0x1cc3890: subl $2028, %esp
0x1cc3896: calll 0x1cc389b ; objc_exception_throw + 17
0x1cc389b: popl %ebx
0x1cc389c: movl $16, (%esp)
0x1cc38a3: calll 0x1cd6678 ; symbol stub for: __cxa_allocate_exception
0x1cc38a8: movl %eax, %esi
0x1cc38aa: movl 8(%ebp), %eax
0x1cc38ad: movl %eax, (%esp)
0x1cc38b0: calll *1722297(%ebx)
0x1cc38b6: movl %eax, %edi
0x1cc38b8: movl 1721937(%ebx), %eax
0x1cc38be: movl %eax, 4(%esp)
0x1cc38c2: movl %edi, (%esp)
0x1cc38c5: calll 0x1cd30a4 ; objc_msgSend
Might it be a bug of iOS 7? Or what?
No problem in the iPad simulator nor on the device.

Trust device, not simulator. Simulator is just that - simulator.

Related

Memory increase when scrolling NSCollectionView images

I'm trying to display pdf pages in a collection view, but accumulate memory in the magnitude of several gigabytes when I scroll the view. The application itself is pretty basic, it's using PDFKit to preload every page of a pdf file as NSImage objects and stores them in an array indexed by an NSCollectionView. The view controller implements the NSCollectionViewDataSource protocol, and set the rendered pdf image from the array as the NSCollectionViewItem image whenever collectionView:itemForRepresentedObjectAtIndexPath: for that index is called. The problem seems to be rooted in the way the pages are rendered to images. There are no memory issues when I use thumbnailOfSize:forBox: to generate NSImages. The application does this concurrently in the background, but the same result can be achieved (for the sake of readability) when it loops on the main thread.
// _width, _height are determined by the pdf
CGSize pdfSize = CGSizeMake(_width, _height);
for (int i = 0; i < _pageCount; i++)
{
PDFPage *page = [_document pageAtIndex:i];
NSImage *pdfImage = [page thumbnailOfSize:pdfSize forBox:kPDFDisplayBoxArtBox];
[_pages replaceObjectAtIndex:i withObject:pdfImage];
}
With this method the application tops around 150 MB in memory usage, also when scrolling. This effectively solves the problem, but my issue with this method is that the the weight of the rendered typeface is a bit too light for the post-processing I intend to do, so I would like to use drawWithBox:toContext: instead. Sadly, that method triggers the memory issue.
// _width, _height are determined by the pdf
CGSize pdfSize = CGSizeMake(_width, _height);
CGRect pdfRect = CGRectMake(0.0f, 0.0f, _width, _height);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gfxcontext = CGBitmapContextCreate(nil, (size_t)_width, (size_t)_height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextSetRGBFillColor(gfxcontext, 1.0f, 1.0f, 1.0f, 1.0f);
CGContextSetInterpolationQuality(gfxcontext, kCGInterpolationHigh);
for (int i = 0; i < _pageCount; i++)
{
PDFPage *page = [_document pageAtIndex:i];
CGContextFillRect(gfxcontext, pdfRect);
[page drawWithBox:kPDFDisplayBoxBleedBox toContext:gfxcontext];
CGImageRef cgPdfImage = CGBitmapContextCreateImage(gfxcontext);
NSImage *nsPdfImage = [[NSImage alloc] initWithCGImage:newImage size:pdfSize];
[_pages replaceObjectAtIndex:i withObject:nsimage];
CGImageRelease(newImage);
}
CGColorSpaceRelease(colorSpace);
CGContextRelease(gfxcontext);
Now I can watch the application memory increase from 150 MB to several hundred MB in a few scrolls, and easily well over a GB if I continue scrolling. Profiling allocations in Instruments reveals the issue when comparing the two methods, and the major difference is that QuartzCore allocates substantial chunks of memory (assuming image data) when I scroll the page.
It seems that mmap is what actually causes the memory increase. From what I understand, mmap is a Unix system call that implements "demand paging" which is obviously what I want, and likely works as intended in the first method. The image data seems to be retained in memory in the second method instead of being paged. The associated assembly may or may not be relevant.
+0x00 pushq %rbp
+0x01 movq %rsp, %rbp
+0x04 pushq %r15
+0x06 pushq %r14
+0x08 pushq %r12
+0x0a pushq %rbx
+0x0b testq %rsi, %rsi
+0x0e je "mmap+0x6e"
+0x10 movl %ecx, %r12d
+0x13 movl %ecx, %eax
+0x15 andl $3, %eax
+0x18 je "mmap+0x6e"
+0x1a movl %r8d, %ebx
+0x1d movq %rsi, %r14
+0x20 movl %r12d, %ecx
+0x23 orl $262144, %ecx
+0x29 callq "0x7ff81b738594"
+0x2e movq %rax, %r15
+0x31 leaq 240919(%rip), %rax
+0x38 movq (%rax), %rax
+0x3b testq %rax, %rax
+0x3e je "mmap+0x7f"
+0x40 andl $4278190080, %ebx
+0x46 orl $16, %ebx
+0x49 btl $12, %r12d
+0x4e movl $144, %edi
+0x53 cmovbl %ebx, %edi
+0x56 leaq 256718(%rip), %rcx
+0x5d movl (%rcx), %esi
+0x5f movq %r14, %rdx
+0x62 xorl %ecx, %ecx
+0x64 movq %r15, %r8
+0x67 xorl %r9d, %r9d
+0x6a callq *%rax
+0x6c jmp "mmap+0x7f"
+0x6e movl $22, %edi
+0x73 callq "0x7ff81b7382f1"
+0x78 movq $-1, %r15
+0x7f movq %r15, %rax
+0x82 popq %rbx
+0x83 popq %r12
+0x85 popq %r14
+0x87 popq %r15
+0x89 popq %rbp
+0x8a retq
The Annotations view in Instruments simply says 100.00% +0x6c jmp "mmap+0x7f. My confusion is that the memory increase is caused by mmap during scrolling, but the problem seems to be rooted in the way NSImage is generated. I assume thumbnailOfSize:forBox: does a lot of optimization behind the curtains, while it is quite straightforward in the second method. What can I do to make the second method work?
Update
This looks like a bug. The memory issue is triggered by the colorspace used to generate image data. Setting the colorspace to NSScreen.mainScreen.colorSpace.CGColorSpace solves the memory issue in the second method, but can be reintroduced by connecting an external monitor while the application is running for both methods. Unlikely a feature.

Subclass as Delegate

I have spent quite a lot of time searching for this answer, but I'm estimating that it is my newbie status that is preventing me from seeing the light.
I am subclassing UIScrollView to make it into an infinite pager. As part of that, I need to see when a new page comes up, as I intend to only have three "pages" in use at a time for memory conservation. That means I need to have my subclass also act as a delegate.
I have followed the directions of: https://stackoverflow.com/a/9986842/773329. But I am running into some strange (to me) problems.
The primary one here is that when I override setDelegate:(id<UIScrollViewDelegate>), to insert the user's delegate, I get a loop in assembly that does not exit:
-(void)setDelegate:(id<UIScrollViewDelegate>)delegate {
_selfDelegate->_userDelegate = delegate;
super.delegate = nil;
super.delegate = (id)_selfDelegate;
}
The assembly:
libobjc.A.dylib`objc_release:
0x12be090: pushl %ebp
0x12be091: movl %esp, %ebp
0x12be093: subl $8, %esp
0x12be096: calll 0x12be09b ; objc_release + 11
0x12be09b: popl %ecx
0x12be09c: movl 8(%ebp), %eax
0x12be09f: testl %eax, %eax
0x12be0a1: je 0x12be0d5 ; objc_release + 69
0x12be0a3: movl (%eax), %edx ; <<< This is where the loop is
0x12be0a5: movl 16(%edx), %edx
0x12be0a8: andl $-4, %edx
0x12be0ab: testb $2, 2(%edx)
0x12be0af: je 0x12be0c5 ; objc_release + 53
0x12be0b1: movl 1002149(%ecx), %ecx
0x12be0b7: movl %ecx, 4(%esp)
0x12be0bb: movl %eax, (%esp)
0x12be0be: calll 0x12bd08c ; objc_msgSend
0x12be0c3: jmp 0x12be0d5 ; objc_release + 69
0x12be0c5: movl %eax, (%esp)
0x12be0c8: movl $0, 4(%esp)
0x12be0d0: calll 0x12bf9d0 ; -[NSObject release]
0x12be0d5: addl $8, %esp
0x12be0d8: popl %ebp
0x12be0d9: ret
Is there something that might be causing the problem?
Based upon what you are doing, I think a UICollectionView would fit perfectly with what you want to accomplish. This removes you from having to write your own code for reusing views and other things you would have to do in order to have performant code.
UICollectionView Reference
You absolutely can and should implement infinite scrolling by using a regular delegate. Which particular functionality are you looking to override inside your subclass?

Unexplained bad access error

I have some code where I iterate through an array. I am adding a second mutable array so that I can add objects to it, which I wish to remove after the iteration is complete. This however is causing bad access errors when I attempt to add the object to the second array I created. This is confusing me, because the object I am trying to add can be used for all types of things, just not adding to this array. This lead me to believe that maybe the array was getting released, so I retained it, but that had no effect. Here is the code:
CCTMXObjectGroup *objectGroup = [ self objectGroupNamed: #"object" ];
NSMutableArray *objectsToRemove = [ NSMutableArray array ];
for ( NSDictionary *object in [ objectGroup objects ] ) {
[ objectsToRemove addObject: object ]; // crash occurs here
// name, type, x, y, width, height
NSString *name = [ object valueForKey: #"name" ];
if ( [ name isEqualToString: #"sprite" ] ) {
[ self createSpriteFromObject: object ];
} else if ( [ name isEqualToString: #"spriteController" ] ) {
[ self createSpriteControllerFromObject: object ];
}
}
If I remove the addObject line, the crash will no longer occur. Here is the kicker, the crash only seems to occur on the 6th iteration. Stepping through the code, the mutable array I am adding to, and the object that I am adding to it both seem to be fine (not released). Why the bad access error then?
Edit
CoreFoundation`-[__NSArrayM addObject:]:
0x23c39e0: pushl %ebp
0x23c39e1: movl %esp, %ebp
0x23c39e3: pushl %edi
0x23c39e4: pushl %esi
0x23c39e5: subl $16, %esp
0x23c39e8: calll 0x23c39ed ; -[__NSArrayM addObject:] + 13
0x23c39ed: popl %edi
0x23c39ee: movl 1512267(%edi), %eax
0x23c39f4: movl %eax, 4(%esp)
0x23c39f8: movl 8(%ebp), %esi
0x23c39fb: movl %esi, (%esp)
0x23c39fe: calll 0x24e35c8 ; symbol stub for: objc_msgSend
0x23c3a03: movl 1512287(%edi), %ecx
0x23c3a09: movl %eax, 12(%esp)
0x23c3a0d: movl 16(%ebp), %eax
0x23c3a10: movl %eax, 8(%esp)
0x23c3a14: movl %ecx, 4(%esp)
0x23c3a18: movl %esi, (%esp)
0x23c3a1b: calll 0x24e35c8 ; symbol stub for: objc_msgSend
0x23c3a20: addl $16, %esp ; bad access code 2
0x23c3a23: popl %esi
0x23c3a24: popl %edi
0x23c3a25: popl %ebp
0x23c3a26: ret
0x23c3a27: nopw (%eax,%eax)
and
libsystem_sim_c.dylib`bzero$VARIANT$sse42:
0x1f9c200: pushl %ebp
0x1f9c201: movl %esp, %ebp
0x1f9c203: pushl %edi
0x1f9c204: movl 8(%ebp), %edi
0x1f9c207: movl 12(%ebp), %edx
0x1f9c20a: xorl %eax, %eax
0x1f9c20c: cmpl $80, %edx
0x1f9c20f: jg 0x1f9c24c ; bzero$VARIANT$sse42 + 76
0x1f9c211: cmpl $12, %edx
0x1f9c214: jge 0x1f9c226 ; bzero$VARIANT$sse42 + 38
0x1f9c216: testl %edx, %edx
0x1f9c218: je 0x1f9c246 ; bzero$VARIANT$sse42 + 70
0x1f9c21a: movb %al, (%edi) ; bad access code 2
0x1f9c21c: incl %edi
NSMutableArray *objectsToRemove = [ NSMutableArray array ];
for ( NSDictionary *object in [ objectGroup objects ] ) {
[ objectsToRemove addObject: object ]; // crash occurs here
If the crash is occurring there, then it can't have anything to do with objectsToRemove (unless there is code you haven't shown).
It means that the object is bunko. Likely, it has been released out from under objectGroup. Turn on Zombie detection and re-run your app.
Note: It can be daunting to debug this stuff when you are new. Some tips:
• If you are staring at assembly code, you are almost assuredly off in the weeds.
• If you are crashing in a Foundation framework method, it is pretty much guaranteed the bug is elsewhere because those methods get executed hundreds of millions of time to boot your Mac or your iOS device. Assuming they work is a safe bet.
It turns out the issue lay with the NSMutableArray initialization. I was using:
NSMutableArray *objectsToRemove = [ NSMutableArray array ];
When it should have been:
NSMutableArray *objectsToRemove = [ NSMutableArray arrayWithCapacity: 10 ];

Simple NSOperationQueue ends in EXC_BAD_ACCESS

NSBlockOperation *blockOperation = ^{NSLog(#"This is an NSBlockOperation");};
NSOperationQueue *ownQueue = [[NSOperationQueue alloc] init];
[ownQueue setMaxConcurrentOperationCount:2];
[ownQueue addOperation:blockOperation];
I am just trying out NSBlockOperation, however this simple code ends with a EXC_BAD_ACCESS.
The code is in main and surrounded by #autorelease.
libsystem_c.dylib`OSAtomicCompareAndSwapIntBarrier$VARIANT$mp:
0x7fff8b8dc524: movl %edi, %eax
libsystem_c.dylib`OSAtomicCompareAndSwap32$VARIANT$mp + 2:
0x7fff8b8dc526: lock
0x7fff8b8dc527: cmpxchgl%esi, (%rdx)
0x7fff8b8dc52a: sete %al
0x7fff8b8dc52d: movzbl %al, %eax
0x7fff8b8dc530: ret
0x7fff8b8dc531: nopl (%rax)
The Program stops and points at 0x7fff8b8dc526: lock
You try to assign a block to a NSBlockOperation, but that are different types. Correct is
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(#"This is an NSBlockOperation");
}];

AdMob crashes the app xcode iPhone

because the iAd does not work all around the world i decided to try out the AdMob
the problem is that when i start the app there are no errors but when i press play game
the whole app crashes
error ->
[GADBannerView private]: unrecognized selector sent to instance 0x9159e50 2012-07-30 09:14:12.676 app[1323:c07] * Terminating app
due to uncaught exception 'NSInvalidArgumentException', reason:
'-[GADBannerView private]: unrecognized selector sent to instance
0x9159e50'
code ->
.h
#import "GADBannerView.h"
GADBannerView *_AbMob;
#property(nonatomic,retain) GADBannerView *AbMob;
.m
_AbMob =[[GADBannerView alloc]initWithFrame:CGRectMake(0.0,self.view.frame.size.height-195, 320, 50)];
_AbMob.adUnitID = #"myNumber";
_AbMob.rootViewController = self;
[self.view addSubview:_AbMob];
GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
breakpoint->
app`-[GADBannerView adSize] at GADBannerView.m:100:
0x1f5c2: pushl %ebp
0x1f5c3: movl %esp, %ebp
0x1f5c5: pushl %esi
0x1f5c6: subl $20, %esp
0x1f5c9: calll 0x1f5ce ; -[GADBannerView adSize] + 12 at GADBannerView.m:101
0x1f5ce: popl %esi
0x1f5cf: movl 217414(%esi), %eax
0x1f5d5: movl %eax, 4(%esp)
0x1f5d9: movl 12(%ebp), %eax
0x1f5dc: movl %eax, (%esp)
0x1f5df: calll 0x32022 ; symbol stub for: objc_msgSend
0x1f5e4: movl 217442(%esi), %ecx
0x1f5ea: movl %ecx, 4(%esp)
0x1f5ee: movl %eax, (%esp)
0x1f5f1: calll 0x32022 ; symbol stub for: objc_msgSend
0x1f5f6: movl 8(%ebp), %ecx
0x1f5f9: testl %eax, %eax
0x1f5fb: je 0x1f618 ; -[GADBannerView adSize] + 86 at GADBannerView.m:101
0x1f5fd: movl 217402(%esi), %edx
0x1f603: movl %edx, 8(%esp)
0x1f607: movl %eax, 4(%esp)
0x1f60b: movl %ecx, (%esp)
0x1f60e: calll 0x32034 ; symbol stub for: objc_msgSend_stret
0x1f613: addl $16, %esp
0x1f616: jmp 0x1f62f ; -[GADBannerView adSize] + 109 at GADBannerView.m:101
0x1f618: movl $0, 4(%ecx)
0x1f61f: movl $0, (%ecx)
0x1f625: movl $0, 8(%ecx)
0x1f62c: addl $20, %esp
0x1f62f: popl %esi
0x1f630: popl %ebp
0x1f631: ret $4
exception at 0x1f5e4: movl 217442(%esi), %ecx
I just ran into this problem too. I used the -all_load linker flag.
Here is the link you need.
https://developers.google.com/mobile-ads-sdk/docs/#incorporating