2016-08-26 16 views
15

क्या उत्पादन में ऑटोलायआउट बाधाओं की अस्पष्टता को पकड़ना संभव है - UIViewAlertForUnsatisfiableConstraints ब्रेकपॉइंट के बराबर लेकिन उत्पादन ऐप्स के लिए?उत्पादन UIViewAlertForUnsatisfiableConstraints उत्पादन में

मेरा लक्ष्य एक वैश्विक हैंडलर जोड़ना होगा जो लॉगिंग सिस्टम में ऐसी त्रुटियों की रिपोर्ट करेगा।

_UIViewAlertForUnsatisfiableConstraints(NSLayoutConstraint* unsatisfiableConstraint, NSArray<NSLayoutConstraint*>* allConstraints):

+0

यह एक अच्छा सवाल है। जैसा कि मैं इसे समझता हूं, प्रतीकात्मक ब्रेकपॉइंट्स आपको एक विशिष्ट प्रतीक, विधि या चयनकर्ता को तोड़ने की अनुमति देता है।मैंने ग्लोबल सी फ़ंक्शन 'UIViewAlertForUnsatisfiableConstraints()' को बाहर करने का प्रयास किया है और यह देखने के लिए देख रहा हूं कि यह 'UIView' पर एक उदाहरण या क्लास विधि है लेकिन मुझे अभी तक कुछ भी नहीं मिला है। – JAL

उत्तर

5

प्रतीक UIViewAlertForUnsatisfiableConstraints वास्तव में एक समारोह है।

यह निजी है, इसलिए आप इसे प्रतिस्थापित नहीं कर सकते हैं।

लेकिन इसे निजी विधि -[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:] से बुलाया जाता है, जिसे तेज किया जा सकता है। ,

void -[UIView engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:] { 
    if ([self _isUnsatisfiableConstraintsLoggingSuspended]) { 
    [self _recordConstraintBrokenWhileUnsatisfiableConstraintsLoggingSuspended:$arg4]; // add constraint to some pool 
    } 
    else { 
    if (__UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints) { 
     // print something in os_log 
    } 
    else { 
     _UIViewAlertForUnsatisfiableConstraints($arg4, $arg5); 
    } 
    } 
} 

अगर मैं this article से सही ढंग से समझ, __UIConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints हमेशा iOS पर कोई वापस आ जाएगी तो तुम सब करने की जरूरत है निजी bool संपत्ति _isUnsatisfiableConstraintsLoggingSuspended कहा जाता है की जाँच करें और मूल विधि तो कॉल करने के लिए है: यह विधि लगभग इस सामग्री है।

इस परिणाम कोड उदाहरण है:

#import <objc/runtime.h> 

void SwizzleInstanceMethod(Class classToSwizzle, SEL origSEL, Class myClass, SEL newSEL) { 
    Method methodToSwizzle = class_getInstanceMethod(classToSwizzle, origSEL); 
    Method myMethod = class_getInstanceMethod(myClass, newSEL); 
    class_replaceMethod(classToSwizzle, newSEL, method_getImplementation(methodToSwizzle), method_getTypeEncoding(methodToSwizzle)); 
    class_replaceMethod(classToSwizzle, origSEL, method_getImplementation(myMethod), method_getTypeEncoding(myMethod)); 
} 

@interface InterceptUnsatisfiableConstraints : NSObject 
@end 

@implementation InterceptUnsatisfiableConstraints 

+ (void)load { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    SEL willBreakConstantSel = NSSelectorFromString(@"engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:"); 
    SwizzleInstanceMethod([UIView class], willBreakConstantSel, [self class], @selector(pr_engine:willBreakConstraint:dueToMutuallyExclusiveConstraints:)); 
    }); 
} 

- (void)pr_engine:(id)engine willBreakConstraint:(NSLayoutConstraint*)constraint dueToMutuallyExclusiveConstraints:(NSArray<NSLayoutConstraint*>*)layoutConstraints { 
    BOOL constrainsLoggingSuspended = [[self valueForKey:@"_isUnsatisfiableConstraintsLoggingSuspended"] boolValue]; 
    if (!constrainsLoggingSuspended) { 
    NSLog(@"_UIViewAlertForUnsatisfiableConstraints would be called on next line, log this event"); 
    } 
    [self pr_engine:engine willBreakConstraint:constraint dueToMutuallyExclusiveConstraints:layoutConstraints]; 
} 

@end 

यह आईओएस 8.2/9/10 (यह आईओएस 8.1 में काम नहीं करता है, तो सावधान रहना होगा) पर काम करता है, लेकिन मैं किसी भी गारंटी नहीं दे सकता। इसके अलावा, यह सिस्टम घटकों, जैसे कुंजीपटल/वीडियो प्लेयर/आदि में बाधा समस्याओं को पकड़ता है। यह कोड नाजुक है (यह किसी भी सिस्टम संस्करण अद्यतन, पैरामीटर परिवर्तन, आदि पर क्रैश हो सकता है) और मैं इसे उत्पादन में उपयोग करने की अनुशंसा नहीं करूंगा (अनुमान लगाएं कि यह स्वचालित समीक्षा प्रक्रिया भी पास नहीं करेगा)। आपके पास अंतिम शब्द है, लेकिन आपको चेतावनी दी गई है।

हालांकि मुझे लगता है कि आप उत्पादन से पहले ऑटोलायआउट में बग को ठीक करने के लिए आंतरिक/बाहरी परीक्षकों के निर्माण में इसका उपयोग कर सकते हैं।

नोटिस कि आप तेजी से उपयोग कर रहे हैं: आप इस कोड को अपने स्विफ्ट प्रोजेक्ट में ब्रिजिंग हेडर फ़ाइल के साथ जोड़ सकते हैं।

+0

कूल! '_UIViewAlertForUnsatisfiableConstraints' के लिए विधि घोषणा कैसे मिली? – JAL

+0

@ जेएएल मैंने थोड़ा सा रिवर्स इंजीनियरिंग किया और कुछ समय मेरे टेस्ट प्रोजेक्ट को डीबग करने में बिताया। –

+0

क्या आप इस बारे में विस्तृत जानकारी दे सकते हैं कि आप इंजीनियर यूआईकिट को कैसे उलटा करते हैं? मैं अपने आंतरिक के बारे में अधिक जानना चाहता हूं, और इस सी समारोह को किसी भी निजी शीर्षलेख में नहीं देखा। क्या आपने टूटी बाधाओं के साथ एक ऐप बनाया और बाइनरी को अलग किया? – JAL

0

संक्षिप्त उत्तर है, यह एक निजी एपीआई है और आप संबंधित खतरों को जानने के बिना उत्पादन कोड में इसके साथ खिलवाड़ नहीं किया जाना चाहिए ...

... कम से कम नहीं:

ए) एप्पल होगा यदि आप ऐप स्टोर में सबमिट किए गए उत्पाद में एसपीआई को ओवरराइड करने का प्रयास करते हैं तो अपने ऐप को अस्वीकार कर दें। और अगर यह किसी कारण से फिसल जाता है, तो वे इसे बाद की तारीख में पकड़ लेंगे, और यह आमतौर पर बदतर है।

बी) विधि का स्विंगिंग, जैसे कि @ रोमन ने अपने उत्तर में उल्लेख किया है, अक्सर आप जो भी काम कर रहे हैं उसे अस्थिर करने की कुछ संभावनाएं लाते हैं (या भविष्य में)। मुझे अभी भी चिंता है जब मैं एक थर्ड पार्टी लाइब्रेरी का उपयोग करता हूं कि कोई इस तरह हुड के नीचे कुछ भंगुर कर रहा है।

वहां उन चेतावनियों के साथ, आगे बढ़ें, निजी तरीकों को ओवरराइड करें और उन्हें अपने दिल की सामग्री में घुमाएं। बस कृपया उस कोड को शिप न करें।

संबंधित मुद्दे