Why is rotating an NSImageView crashing my app? - macos

I'm making a macOS app and I've got this code used to rotate an image:
didSet {
let degreesToRotate = oldValue - phoneXRotation
phoneImageView.rotate(byDegrees: CGFloat(degreesToRotate))
degreesLabel.isHidden = false
degreesLabel.stringValue = "\(phoneXRotation)"
if phoneXRotation > 70 {
statusLabel.stringValue = "Phone orientation: Right Tilt"
} else if phoneXRotation < -70 {
statusLabel.stringValue = "Phone orientation: Left Tilt"
} else {
statusLabel.stringValue = "Phone orientation: Flat"
}
}
The app will randomly crash in an lldb error. If I comment out the third line that rotate the phone, I have no problems. The conversion from Int to CGFloat shouldn't crash. Any ideas?
Here is the stack trace:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x00007fff8989b44e AppKit`-[NSApplication _crashOnException:] + 109
frame #1: 0x00007fff8996ea32 AppKit`__37+[NSDisplayCycle currentDisplayCycle]_block_invoke.31 + 708
frame #2: 0x00007fff8ba62d37 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
frame #3: 0x00007fff8ba62ca7 CoreFoundation`__CFRunLoopDoObservers + 391
frame #4: 0x00007fff8ba436d9 CoreFoundation`__CFRunLoopRun + 873
frame #5: 0x00007fff8ba43114 CoreFoundation`CFRunLoopRunSpecific + 420
frame #6: 0x00007fff8afa3ebc HIToolbox`RunCurrentEventLoopInMode + 240
frame #7: 0x00007fff8afa3cf1 HIToolbox`ReceiveNextEventCommon + 432
frame #8: 0x00007fff8afa3b26 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 71
frame #9: 0x00007fff8953ca54 AppKit`_DPSNextEvent + 1120
frame #10: 0x00007fff89cb87ee AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 2796
frame #11: 0x00007fff895313db AppKit`-[NSApplication run] + 926
frame #12: 0x00007fff894fbe0e AppKit`NSApplicationMain + 1237
* frame #13: 0x000000010000691d Dataspeed Mac Project`main at AppDelegate.swift:12
frame #14: 0x00007fffa11f1235 libdyld.dylib`start + 1
frame #15: 0x00007fffa11f1235 libdyld.dylib`start + 1

Related

Using SKTexture:withImageNamed in a for loop to load animations crashes after playing 30 + animation

My code below creates a Texture from an image name from file lookups in a plist like (Duck1_1,Duck1_2,Duck1_3,etc) it loops through them then adds them to a mutable array. The mutable array is then used to animate with the textures stored and played with an SKAction. This works fine for the animations until 30-40 are played then it crashes and says too many files open and it can't open the files anymore. Any ideas on how to stop this from happening?
thanks
//loadPlistForAnimationWithNames function
NSMutableArray *animationToReturn = [NSMutableArray array];
for(NSString *frameNumber in animationFrameNumbers) {
NSString *frameName = [NSString stringWithFormat:#"%#%#.png",animationFramePrefix,frameNumber];
if(frameName!=nil)
[animationToReturn addObject:[SKTexture textureWithImageNamed:frameName]];
}
SKAction *action=nil;
action=[SKAction animateWithTextures:animationToReturn timePerFrame:animationDelay resize:NO restore:NO];
SKAction *repeatAction=nil;
repeatAction = [SKAction repeatAction:action count:1];
[animationToReturn removeAllObjects];
action=nil;
animationFrameNumbers=nil;
return repeatAction;
//Call to loadPlistForAnimationWithNames and run animation
SKAction *action=[animalObject loadPlistForAnimationWithNames:#"duckAnim1" andClassName:NSStringFromClass([self class])];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Duck1_1"];
sprite.position=CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
sprite.size=self.frame.size;
[sprite setZPosition:3];
[self addChild:sprite];
[sprite runAction:action];
Here is the Xcode error I get when it crashes:
: ImageIO: CGImageReadCreateDataWithMappedFile 'open' failed '/private/var/mobile/Containers/Bundle/Application/782E98C3-0452-43EF-BF4D-401773D5FDCD/WildNoizesLite.app/Duck1_1.png'
error = 24 (Too many open files)
Backtrace:
* thread #1: tid = 0x301c4, 0x00000001944ab270 libsystem_kernel.dylib__pthread_kill + 8, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00000001944ab270 libsystem_kernel.dylib__pthread_kill + 8
frame #1: 0x0000000194549170 libsystem_pthread.dylibpthread_kill + 112
frame #2: 0x0000000194422b18 libsystem_c.dylibabort + 112
frame #3: 0x00000001934b5418 libc++abi.dylibabort_message + 116
frame #4: 0x00000001934d4b8c libc++abi.dylibdefault_terminate_handler() + 304
frame #5: 0x0000000193ce83c0 libobjc.A.dylib_objc_terminate() + 128
frame #6: 0x00000001934d1bb4 libc++abi.dylibstd::__terminate(void (*)()) + 16
frame #7: 0x00000001934d173c libc++abi.dylib__cxa_rethrow + 144
frame #8: 0x0000000193ce8294 libobjc.A.dylibobjc_exception_rethrow + 44
frame #9: 0x0000000181ef5384 CoreFoundationCFRunLoopRunSpecific + 572
frame #10: 0x000000018b94b6fc GraphicsServicesGSEventRunModal + 168
frame #11: 0x0000000186af2f40 UIKitUIApplicationMain + 1488
* frame #12: 0x0000000100174fa0 Wild Noizesmain(argc=1, argv=0x000000016fd6f9d8) + 124 at main.m:16
frame #13: 0x0000000194392a08 libdyld.dylib`start + 4

App freezes when resizing window?

I'm working on a menubar application and I've made a custom (borderless) NSWindow which I've added programmatically. For some reason when I try to resize the window, it freezes and I'm unable to resize the window and open the menu-bar menu. However I can still move the window but not click things in it. The weird thing is that there is no error message at all, even though I turned on breakpoints and NSZombieMode. So I've no idea what the problem could be.
// customWindow.m
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(NSUInteger)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag {
// Using NSBorderlessWindowMask results in a window without a title bar.
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask | NSResizableWindowMask backing:NSBackingStoreBuffered defer:NO];
if (self != nil) {
if (![[SharedClass sharedManager] lastColor]) {
[self setBackgroundColor:[NSColor colorWithRed:(float)252/255 green:(float)249/255 blue:(float)151/255 alpha:1]];
[[SharedClass sharedManager] setLastColor:self.backgroundColor];
} else {
[self setBackgroundColor: [[SharedClass sharedManager] lastColor]];
}
[self setLevel:NSNormalWindowLevel];
// Start with no transparency for all drawing into the window
// Turn off opacity so that the parts of the window that are not drawn into are transparent.
[self setOpaque:NO];
// [self setBackgroundColor:[NSColor clearColor]];
[self setHasShadow:YES];
[self setMovableByWindowBackground:YES];
[self makeKeyAndOrderFront:theTextView];
panel = [NSColorPanel sharedColorPanel];
[panel setTarget:self];
[panel setColor:self.backgroundColor];
[panel setAction:#selector(colorUpdate:)];
[panel setShowsAlpha:YES];
[self setDelegate:self];
NSRect cFrame = [self frame];
NSView *theView = [[NSView alloc] initWithFrame:cFrame];
[self setContentView:theView];
[self setMinSize:CGSizeMake(100, 100)];
}
return self;
}
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize {
exit.frame = NSMakeRect(2,(frameSize.height-12), 10, 10);
palette.frame = NSMakeRect((frameSize.width-24),(frameSize.height-12), 10, 10);
locker.frame = NSMakeRect((frameSize.width-12),(frameSize.height-12), 10, 10);
theTextView.frame = NSRectFromCGRect(CGRectMake(0, 8, frameSize.width, (frameSize.height-20)));
return frameSize;
}
- (void)windowDidResize:(NSNotification *)notification{
NSLog(#"resized");
}
Stack trace :
0 DDHotKey 0x00000001000044ed -[CustomWindow windowDidResize:] + 61
1 CoreFoundation 0x00007fff9034245c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
2 CoreFoundation 0x00007fff90232634 _CFXNotificationPost + 3140
3 Foundation 0x00007fff8d7f59d1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
4 AppKit 0x00007fff89117770 -[NSWindow _setFrameCommon:display:stashSize:] + 2885
5 AppKit 0x00007fff891d4b73 -[NSWindow setFrame:display:animate:] + 641
6 DDHotKey 0x000000010000a8c0 -[DDHotKeyAppDelegate setFrame:animated:] + 416
7 DDHotKey 0x00000001000091ae __53-[DDHotKeyAppDelegate applicationDidFinishLaunching:]_block_invoke + 2318
8 AppKit 0x00007fff895e5233 GlobalObserverHandler + 117
9 HIToolbox 0x00007fff88d0ab6c _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1260
10 HIToolbox 0x00007fff88d09fae _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 386
11 HIToolbox 0x00007fff88d09e22 SendEventToEventTargetWithOptions + 43
12 HIToolbox 0x00007fff88d46a9e _ZL29ToolboxEventDispatcherHandlerP25OpaqueEventHandlerCallRefP14OpaqueEventRefPv + 1762
13 HIToolbox 0x00007fff88d0b295 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 3093
14 HIToolbox 0x00007fff88d09fae _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 386
15 HIToolbox 0x00007fff88d1fcb6 SendEventToEventTarget + 40
16 AppKit 0x00007fff890d71a2 _DPSNextEvent + 3001
17 AppKit 0x00007fff890d5f68 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
18 AppKit 0x00007fff890cbbf3 -[NSApplication run] + 594
19 AppKit 0x00007fff89048354 NSApplicationMain + 1832
20 DDHotKey 0x0000000100007312 main + 34
21 libdyld.dylib 0x00007fff8bd335c9 start + 1

Cocoa event loop blocks while tracking a menu

I maintain a legacy OSX application that instead of calling NSApplicationMain() to process events, runs an event loop on the main thread that looks like this:
...
do {
event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast
inMode: NSDefaultRunLoopMode dequeue:YES];
[self handleEvent:event];
}
} while(event != nil);
...
Everything works until I activate the application's menu. Once the menu is active, nextEventMatchingMask blocks forever. I can see in lldb that osx starts another modal event loop (carbon?) which causes the cococa's one to block:
frame #2: 0x00007fff92748eb4 CoreFoundation`__CFRunLoopServiceMachPort + 212
frame #3: 0x00007fff9274837b CoreFoundation`__CFRunLoopRun + 1371
frame #4: 0x00007fff92747bd8 CoreFoundation`CFRunLoopRunSpecific + 296
frame #5: 0x00007fff8c11c56f HIToolbox`RunCurrentEventLoopInMode + 235
frame #6: 0x00007fff8c11c2ea HIToolbox`ReceiveNextEventCommon + 431
frame #7: 0x00007fff8c17568a HIToolbox`AcquireNextEventInMode + 54
frame #8: 0x00007fff8c172e2b HIToolbox`IsUserStillTracking(MenuSelectData*, unsigned char*) + 173
frame #9: 0x00007fff8c172a41 HIToolbox`TrackMenuCommon(MenuSelectData&, unsigned char*) + 1661
frame #10: 0x00007fff8c1803c1 HIToolbox`MenuSelectCore(MenuData*, Point, double, unsigned int, OpaqueMenuRef**, unsigned short*) + 510
frame #11: 0x00007fff8c1800fe HIToolbox`_HandleMenuSelection2 + 446
frame #12: 0x00007fff8a9a8de0 AppKit`_NSHandleCarbonMenuEvent + 277
frame #13: 0x00007fff8a8dfd0d AppKit`_DPSNextEvent + 1828
frame #14: 0x00007fff8a8def68 AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
Is there anything I can do to prevent this behaviour ?
Unfortunately I cannot rewrite the application so I need a quick and dirty solution to run the main thread while the menu is active.

Why is the adjustScroll: method being called twice per scroll in NSScrollView?

I have overridden the adjustScroll: method within the documentView of my NSScrollView in order to investigate how to use it to constrain large scroll movements.
What I am seeing is that for each scroll "event" prior to calling the normal scrolling notifications (which I am listening to elsewhere) it calls the adjustScroll method twice(!) and the first time it always seems to call it with a rectangle of size (1,1) - strange?
My method is as follows:
override func adjustScroll(newVisible: NSRect) -> NSRect {
println("Document: adjustScroll: \(newVisible)")
return super.adjustScroll(newVisible)
}
With the results of the println being as follows:
Document: adjustScroll: (1.0, 0.0, 1.0, 1.0)
Document: adjustScroll: (1.0, 0.0, 1436.0, 855.0)
I only have one "Document" object in my view hierarchy and there is only one scrollView...perplexed.
EDIT
I have printed out the stack within the adjustScroll call. The relevant parts are as follows for each of the two calls:
(1.0,1.0)
[0 Grid 0x000000010007d697 _TToFC4Grid8Document12adjustScrollfS0_FVSC6CGRectS1_ + 87,
1 AppKit 0x00007fff84368070 -[_NSScrollingConcurrentMainThreadSynchronizer _scrollToCononicalOrigin] + 655,
2 AppKit 0x00007fff84367a51 -[_NSScrollingConcurrentMainThreadSynchronizer _synchronize:completionHandler:] + 167,
3 AppKit 0x00007fff84367963 __80-[_NSScrollingConcurrentMainThreadSynchronizer initWithSharedData:constantData:]_block_invoke + 144,
4 libdispatch.dylib 0x000000010057ed43 _dispatch_client_callout + 8,
...
(1436.0, 855.0)
[0 Grid 0x000000010007d697 _TToFC4Grid8Document12adjustScrollfS0_FVSC6CGRectS1_ + 87,
1 AppKit 0x00007fff84206f8d -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 1302,
2 AppKit 0x00007fff84368209 -[_NSScrollingConcurrentMainThreadSynchronizer _scrollToCononicalOrigin] + 1064,
3 AppKit 0x00007fff84367a51 -[_NSScrollingConcurrentMainThreadSynchronizer _synchronize:completionHandler:] + 167,
4 AppKit 0x00007fff84367963 __80-[_NSScrollingConcurrentMainThreadSynchronizer initWithSharedData:constantData:]_block_invoke + 144,
5 libdispatch.dylib 0x000000010057ed43 _dispatch_client_callout + 8,
...

How to speed up matplotlib scatter ploting?

I need to draw a batch of scatter charts in matplotlib, and found the speed of matplotlib is slow, then I lineprofile the function, and found the hotspot is fig, ax = plt.subplots(), It costs 56.1% of time to creat a blank figure and axes !!
How to speed it up ? I mean, how can I reuse fig and ax to avoid creating them each time ?
Attach the profile report here (I cut some of the line to make it simple)
Total time: 0.733771 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
517 #profile
518 def df_scatter(df):
519 ''' draw the scatter plot for Pandas dataframe 'df'
533 '''
536
537 1 75 75.0 0.0 biggest_area = 1000
538 1 117 117.0 0.0 mycm = matplotlib.cm.get_cmap('jet') # 'spectral'
539
541 1 78 78.0 0.0 col_qty = len(df.columns)
543
544 1 1859 1859.0 0.1 x = list(df.ix[:,0].values)
545 1 1258 1258.0 0.0 y = list(df.ix[:,1].values)
551
552 1 1472345 1472345.0 56.1 fig, ax = plt.subplots()
556
557 1 7007 7007.0 0.3 plt.subplots_adjust(left=0.07, right=0.92, bottom=0.1, top=0.95)
558 1 179 179.0 0.0 x_margin, y_margin = (max(x)-min(x))/20, (max(y)-min(y))/20
563
564 1 71 71.0 0.0 if col_qty > 2:
565 1 1602 1602.0 0.1 r = list(df.ix[:,2].values)
566 1 309 309.0 0.0 size_r = np.array(biggest_area)*r/max(r)
585
586 1 34712 34712.0 1.3 sc = plt.scatter(x, y, marker='o', s=size_r, cmap=mycm, alpha=0.65)
587
588 # adding colorbar
589 1 542417 542417.0 20.7 cbaxes = fig.add_axes([0.94, 0.25, 0.02, 0.70])
590 1 165719 165719.0 6.3 cbar = plt.colorbar(sc, cax=cbaxes)
591 1 122 122.0 0.0 cbar.solids.set_edgecolor('face')
595
602 1 1061 1061.0 0.0 plt.figtext(0.94,0.10,"%0.1f"%(max(r)), fontproperties=TEXT_FONT_MEDIUM)
639 1 66 66.0 0.0 return fig
I think that the best way to do it is calling
fig = plt.figure()
ax=fig.add_subplot(111)
from outside of df_scatter. Then, pass it to df_scatter as arguments:
df_scatter(df,fig,ax):
or simply do inside df_scatter:
def df_scatter(df):
fig = plt.gcf()
ax = plt.gca()
after the creation of fig & axis was done.

Resources