2017-04-19 7 views
0

최신 MacBook Pro가 출시되면 내 앱에 터치 바 지원이 추가되었습니다. 나중에 내가 이해할 수있는 사용자 정의 이스케이프 키를 비롯하여 다양한 사소한 개선 작업을 수행했습니다. 그 업데이트를 공개 한 후 앱이 이스케이프 키를 업데이트하려고 할 때 크래시 보고서를 받기 시작했습니다.터치 바의 이스케이프 키를 업데이트 할 때이 충돌을 어떻게 막을 수 있습니까?

가 여기에 하나의 예입니다 :

Exception Type: SIGBUS 
Exception Codes: BUS_ADRERR at 0x7fff54a05ff8 
Crashed Thread: 0 

Application Specific Information: 
Selector name found in current argument registers: objectForKey: 

Thread 0 Crashed: 
0 Foundation       0x00007fffacbaea98 -[NSConcreteMapTable objectForKey:] + 21 
1 Foundation       0x00007fffacbfc019 -[NSISEngine outgoingRowHeadForRemovingConstraintWithMarker:] + 214 
2 Foundation       0x00007fffacbfbb4c -[NSISEngine removeConstraintWithMarker:] + 479 
3 Foundation       0x00007fffacbf76a6 -[NSISEngine _flushPendingRemovals] + 615 
4 Foundation       0x00007fffacbf4b06 -[NSISEngine withBehaviors:performModifications:] + 197 
5 AppKit        0x00007fffa8c83760 -[NSView(NSConstraintBasedLayout) _withAutomaticEngineOptimizationDisabled:] + 69 
6 AppKit        0x00007fffa8d129dd -[NSView(NSConstraintBasedLayout) removeConstraints:] + 276 
7 AppKit        0x00007fffa8c88f9e -[NSView(NSConstraintBasedLayout) _constraints_snipDangliesWithForce:] + 595 
8 AppKit        0x00007fffa8c82d9e -[NSView _setSuperview:] + 1076 
9 AppKit        0x00007fffa8c88945 -[NSView removeFromSuperview] + 446 
10 AppKit        0x00007fffa9593eef -[NSTouchBarEscapeKeyViewController setTouchBarItem:] + 145 
11 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 
12 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 
13 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 
… 
509 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 
510 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 
511 AppKit        0x00007fffa9176bf5 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 438 

내가 약 500 라인 삭제 한 간결함을-그들 모두는 [NSApplicationFunctionRowController _updateEscapeKeyItem] + 438

에 대한 호출은 여기에 또 다른 약식 보고서는 것입니다. 이것은 가장 일반적인 충돌입니다. 여기

- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { 

    if ([identifier isEqualToString:JUNTouchBarItemIdentifierCancel]) { 
     NSCustomTouchBarItem *item = [JUNTouchBar cancelButtonItemWithIdentifier:identifier]; 
     return item; 
    } 
    return nil; 

} 

과도 cancelButtonItemWithIdentifier:, 아주 간단 :

touchBar:makeItemForIdentifier: 방법은 바로 이것이다
Exception Type: SIGBUS 
Exception Codes: BUS_ADRERR at 0x7fff5b8c2f74 
Crashed Thread: 0 

Thread 0 Crashed: 
0 CoreText        0x00007fffc87d2e8d _ZNK3OTL7GCommon9NthLookupEj + 41 
1 CoreText        0x00007fffc87d658b _ZNK3OTL4GPOS12ApplyLookupsER8TRunGlueiRNS_12GlyphLookupsE + 155 
2 CoreText        0x00007fffc87d5f53 _ZN26TOpenTypePositioningEngine12PositionRunsER9SyncStateR13KerningStatus + 839 
3 CoreText        0x00007fffc8823920 _ZN14TKerningEngine14PositionGlyphsER8TRunGlue11ShapingTypePK10__CFString + 168 
4 CoreText        0x00007fffc87ddcf7 CTFontTransformGlyphs + 463 
5 UIFoundation       0x00007fffd9d2a795 __NSStringDrawingEngine + 7348 
6 UIFoundation       0x00007fffd9d315ea -[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:context:] + 605 
7 UIFoundation       0x00007fffd9d31efd -[NSAttributedString(NSExtendedStringDrawing) boundingRectWithSize:options:] + 32 
8 AppKit        0x00007fffc4e711cb -[NSAttributedString(NSStringDrawingExtension) _sizeWithSize:] + 55 
9 AppKit        0x00007fffc4e710ff -[NSButtonCell(NSButtonCellPrivate) _titleSizeWithSize:] + 97 
10 AppKit        0x00007fffc4e70eab -[NSButtonCell(NSButtonCellPrivate) _alignedTitleRectWithRect:] + 235 
11 AppKit        0x00007fffc4e25162 -[NSButtonCell cellSizeForBounds:] + 918 
12 AppKit        0x00007fffc4da2a21 -[NSCell cellSize] + 68 
13 AppKit        0x00007fffc4da295a -[NSControl sizeToFit] + 53 
14 AppKit        0x00007fffc520392c +[NSButton(NSButtonConvenience) _buttonWithTitle:image:target:action:] + 421 
15 AppKit        0x00007fffc5203a05 +[NSButton(NSButtonConvenience) buttonWithTitle:target:action:] + 199 
16 Deliveries       0x0000000103b4c655 +[JUNTouchBar cancelButtonItemWithIdentifier:] (JUNTouchBar.m:75) 
17 Deliveries       0x0000000103b67e9b -[JUNEditWindowController touchBar:makeItemForIdentifier:] (JUNEditWindowController.m:183) 
18 AppKit        0x00007fffc57d7d2a __32-[NSTouchBar itemForIdentifier:]_block_invoke + 34 
19 AppKit        0x00007fffc4e71bd0 +[NSAppearance _performWithCurrentAppearance:usingBlock:] + 79 
20 AppKit        0x00007fffc57d7b9b -[NSTouchBar itemForIdentifier:] + 1158 
21 AppKit        0x00007fffc57d868e -[NSTouchBar(NSEscapeKeyReplacementOld) escapeKeyReplacementItem] + 51 
22 AppKit        0x00007fffc5250e80 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 238 
23 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 
24 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 
25 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 
… 
509 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 
510 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 
511 AppKit        0x00007fffc5250f49 -[NSApplicationFunctionRowController _updateEscapeKeyItem] + 439 

: 실제로 나는 그것이 부르고 코드를 의심하지만 실제 문제가되지 않습니다, 내 자신의 코드를 호출

+ (NSCustomTouchBarItem *)cancelButtonItemWithIdentifier:(NSString *)identifier { 
    NSString *title = NSLocalizedString(@"Cancel", nil); 
    NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)]; 
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:80.0]; 
    constraint.priority = 950; 
    constraint.active = YES; 
    NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; 
    item.view = button; 
    return item; 
} 

물론이 충돌을 재현 할 수 없습니다. MacOS 10.12.2에서 10.12.5의 베타 버전을 통해 발생합니다. 대부분의 보고서는 동일한 13 인치 모델에서 나왔습니다. 충돌 보고서에 주석을 포함하는 소수의 사람들은 대부분 새 창을 여는 작업 (즉, 이스케이프 키 변경)이 발생한 직후에 상황이 발생한다고 말합니다. 한 사람이 창문을 닫을 행동을 취한 후 일어 났으며 한 사람은 충돌 이전에 10 초 동안 교수형에 처했다. 같은 방법으로 500 건의 전화가 걸려도 의미가있다. 두 사람이 한 번 이상이 문제를 언급했지만 물론 그들은 연락처 정보를 남기지 않아서 나는 그들과 연락 할 방법이 없다.

나는 나의 맞춤형 탈출 키를 제거함으로써 충돌을 해결할 수 있지만, 나는하지 않을 것을 알고있다. 이 문제를 어떻게 해결할 수 있을지에 대한 아이디어가 있습니까?

업데이트 : 원래이를 올리기 때문에, 나는 제약 조건을 제거하려면 응용 프로그램을 업데이트했습니다, 그래서 지금 얻을 수있는 버튼을 만들기위한 내 코드에 대한 간단하다 :

+ (NSCustomTouchBarItem *)cancelButtonItemWithIdentifier:(NSString *)identifier { 
    NSString *title = JUNLocalizedString(@"Cancel", nil); 
    NSButton *button = [NSButton buttonWithTitle:title target:nil action:@selector(cancelOperation:)]; 
    NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; 
    item.view = button; 
    return item; 
} 

을 불행하게도 나는 아직도 받고 있어요 동일한 스택 추적을 사용하여 새 버전의 충돌 보고서 그래서 문제는 내가 제공하는 버튼으로 생각하지 않습니다.

+0

여기에 대한 설명을 찾았습니까? 나는 그것을보고 있지만 누락 된 스택 맨 아래로 그것을 알아 내기가 어렵습니다 ... – duncanwilcox

+0

@duncanwilcox : 아직 해결책을 찾지 못했습니다. 현재 제약 조건을 제거하여 도움이되는지 확인하거나 아니면 사용자 지정 취소 버튼을 완전히 제거하는 방법에 대해 논쟁 중입니다. 버튼에 제약 조건을 추가하고 있습니까? – robotspacer

+0

여전히 문제가 있으며 제약 조건이 추가되지 않았습니다. – duncanwilcox

답변

1

죄송합니다 답변은 아니지만 의견을 말씀 드리기에는 너무 깁니다.

충돌이 발생한 사용자를 위해 디버그 버전을 구축했습니다. _updateEscapeKeyItem 메서드를 사용하여 무한 재귀에 의해 스택 맨 아래에 날아가는 충돌 원점을 찾아냅니다 .

내 생각 엔 10.13 구현을 근본적으로 바꿨지 만 (그들은 "KORO amok"에 대해 언급 한 바 있습니다.) 단단한 단서가없는 한 10.12 충돌을 조사하지 않을 수도 있습니다.

무한 재귀를 멈추게하는 (주로 How to swizzle a method of a private class에서 빌린) 빠르고 쉽게 코드입니다. 결과 충돌 보고서가 더 유용 할 수 있습니다.

@interface NSObject (swizzle_touchbar_stuff) 
@end 

static NSInteger updateEscapeKeyItem = 0; 

@implementation NSObject (swizzle_touchbar_stuff) 
+ (void)load 
{ 
    static dispatch_once_t onceToken = 0; 
    dispatch_once(&onceToken, ^{ 
     Method original, swizzled; 

     original = class_getInstanceMethod(objc_getClass("NSApplicationFunctionRowController"), NSSelectorFromString(@"_updateEscapeKeyItem")); 
     swizzled = class_getInstanceMethod(self, @selector(sparkle_updateEscapeKeyItem)); 
     method_exchangeImplementations(original, swizzled); 
    }); 
} 

- (void)sparkle_updateEscapeKeyItem 
{ 
    updateEscapeKeyItem++; 
    NSLog(@"sparkle_updateEscapeKeyItem %ld", updateEscapeKeyItem); 
    assert(updateEscapeKeyItem < 10); 
    [(NSObject *)self sparkle_updateEscapeKeyItem]; 
    updateEscapeKeyItem--; 
} 

@end 
+0

이것이 우리가 얻을 수있는 최선의 대답이라고 생각합니다. 이것은 10.13에서 수정 된 것 같아서, 내 자신의 해결 방법은'escapeKeyReplacementItemIdentifier'에 대한 호출을 중심으로'@ available' 체크를 추가하는 것입니다. 따라서 맞춤 esc 키는 10.13 또는 이후 버전에만 표시됩니다. – robotspacer