เฉพาะบน iPad 3 ใหม่เท่านั้น: wait_fences: ไม่สามารถรับการตอบกลับ: 10004003

ฉันรู้ว่ามีคำถามมากมายเกี่ยวกับเรื่องนี้ แต่เท่าที่ฉันสามารถบอกได้ว่านี่เป็นสถานการณ์ที่ไม่เหมือนใคร ฉันก็เลยคิดว่าจะโพสต์มัน หวังว่านี่จะเป็นการเพิ่มข้อมูลที่อาจให้คำตอบว่าทำไมสิ่งนี้ถึงเกิดขึ้นกับเราในที่สุด ฉันได้รับข้อผิดพลาด: wait_fences: failed to gets Reply: 10004003 เมื่ออุปกรณ์ของฉันหมุน ภาพเคลื่อนไหวของมุมมองของฉันเริ่มต้นจาก:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

ฉันเพิ่งได้รับข้อผิดพลาดบน iPad 3 ใหม่ ฉันใช้โปรแกรมเดียวกันนี้กับ iPad และ iPhone รุ่นดั้งเดิมที่มีความเร็วต่ำถึง 3GS พวกเขาทั้งหมดไม่ได้รับข้อผิดพลาด wait_fences และทั้งหมดหมุนได้เร็วกว่าที่ iPad 3 ทำ

ฉันใช้ Core Graphics เกือบทั้งหมดเพื่อวาดมุมมอง ฉันยังตรวจสอบให้แน่ใจว่าพวกเขาถูกวาดใหม่ตามการปรับขนาด ดังนั้นฉันจึงไม่ได้รับมุมมองที่เป็นพิกเซล หากฉันปิดใช้งานการวาดใหม่เมื่อปรับขนาด ฉันจะไม่ได้รับข้อผิดพลาดนี้ (แต่ฉันได้รับมุมมองที่ขยาย) หากฉันปิดใช้งานการวาดภาพกราฟิกหลักโดยสิ้นเชิง ฉันจะไม่ได้รับข้อผิดพลาด (แต่แน่นอนว่า ฉันได้รับมุมมองสีดำ)

ฉันใช้ Time Profiler และพบว่าการวางสายนั้นเกิดจากการไล่ระดับสีเป็นหลัก: ป้อนคำอธิบายรูปภาพที่นี่

ฉันได้แก้ไขโค้ดให้เติมแทนที่จะวาดการไล่ระดับสี และนั่นจะช่วยบรรเทาปัญหาได้ ฉันจะบอกว่าการไล่ระดับสีเป็นปัญหายกเว้นฉันทำแอนิเมชั่นเหล่านี้ในสถานการณ์อื่น (นอกเหนือจากการตอบสนองต่อการหมุน) และมันก็ใช้ได้ดี

ฉันอยากจะทราบด้วยว่าฉันได้ให้ความสนใจเป็นพิเศษเพื่อให้แน่ใจว่าฉันจะเคลื่อนไหวเฉพาะมุมมองที่อยู่บนหน้าจอเท่านั้น ฉันรู้ว่าบางครั้งการแสดงภาพเคลื่อนไหวนอกหน้าจออาจทำให้เกิดข้อผิดพลาดนี้ได้

ฉันยังไม่ได้รวมโค้ดภาพเคลื่อนไหว

มีความคิดใด ๆ ว่าทำไมสิ่งนี้ถึงเกิดขึ้น? โดยเฉพาะอย่างยิ่งเมื่อมันเกิดขึ้นบน iPad 3 เท่านั้น?

สำหรับผู้ที่จะถาม นี่คือโค้ดที่ใช้สร้างแอนิเมชัน โดยปกติแล้วจะถูกรวมไว้ใน UIView Animation Block

- (void) setFramesForFocusView:(CustomControl *)focusView atX:(CGFloat)x showInput:(BOOL)showInput{
    CGSize bSize = self.bounds.size;
    CGRect fRect = focusView.frame;
    fRect.size.width = bSize.width;

    CGRect iRect;
    if (focusView.inputViewIsSystemKeyboard){
        if (_keyboardRect.origin.y < 0 || _keyboardRect.origin.y >= CGRectGetMaxY(self.bounds) || CGRectIsEmpty(_keyboardRect) || CGRectGetMaxY(_keyboardRect) > CGRectGetMaxY(self.bounds)) return;
        iRect = _keyboardRect;
    } else {
        iRect = (focusView.inputUIView && showInput) ? CGRectMake(0, bSize.height / 2, bSize.width, bSize.height / 2) : CGRectZero;
    }

    CGRect iaRect = focusView.inputAccessoryUIView.frame;
    CGFloat availableFieldHeight = iRect.origin.y - iaRect.size.height;

    iRect.size.width = bSize.width;
    iaRect.size.width = bSize.width;

    if (!showInput){
        iRect.origin.y = bSize.height;
    }
    iaRect.origin.y = iRect.origin.y - iaRect.size.height;

    iRect.origin.x = x;
    iaRect.origin.x = x;
    focusView.inputUIView.frame = iRect;
    focusView.inputAccessoryUIView.frame = iaRect;

    if (focusView.expandInput){
        fRect.origin.y = 0;
        fRect.size.height = availableFieldHeight;
    } else {
        if (focusView.labelPlacement != LabelPlacementTop && focusView.labelPlacement != LabelPlacementBottom){
            fRect.size.height = _currentView.storedFrame.size.height + [focusView.label.text sizeWithFont:focusView.label.font].height; 
        }
        fRect.origin.y = availableFieldHeight - fRect.size.height;
    }
    if (fRect.size.height > availableFieldHeight){
        fRect.origin.y = 0;
        fRect.size.height = availableFieldHeight;
    }
    fRect.origin.x = x;
    [focusView setLabelPlacement:LabelPlacementTop toFrame:fRect];
}

person Aaron Hayman    schedule 07.06.2012    source แหล่งที่มา
comment
ความจริงที่ว่ามันเกิดขึ้นบน iPad 3 เท่านั้น ส่วนใหญ่ชี้ให้เห็นว่ามันเป็นปัญหาเรื่องจังหวะที่ iPad 3 นั้นเร็วพอที่จะกระตุ้นได้ มันไม่ได้แนะนำเป็นพิเศษว่าถูกต้องบนแพลตฟอร์มอื่น เพียงแต่ว่าคุณโชคดีบนแพลตฟอร์มอื่น คำตอบอื่นๆ โดยเฉพาะอย่างยิ่งเกี่ยวกับภาพเคลื่อนไหวเริ่มต้น/สิ้นสุดที่ไม่ตรงกัน หรือการเคลื่อนไหวเมื่ออยู่นอกหน้าจอ อาจยังคงใช้ได้อยู่   -  person Rob Napier    schedule 07.06.2012
comment
ฉันไม่สามารถพูดได้ว่าสิ่งนี้มีความเกี่ยวข้องเพียงใดเนื่องจากฉันมีประสบการณ์น้อยกับ CoreAnimation แต่ Marco Arment ได้พูดคุยถึงปัญหาเฉพาะของ iPad 3 กับ CA renderInContext ที่เกิดจากฮาร์ดแวร์กราฟิกสุดเก๋ในนั้น ดูการสนทนานี้ได้ในพอดแคสต์ Build and Analyze ตอนที่ 72 เริ่มตั้งแต่เวลา 56:20 น. ฉันคิดว่าผลที่สุดคือ iPad ทำงานช้าลง บางทีบางสิ่งบางอย่างสามารถรวบรวมได้?   -  person Swizzlr    schedule 07.06.2012
comment
@RobNapier ใช่แล้ว คุณทำถูกแล้ว ฉันใช้เวลามากมายเพื่อให้แน่ใจว่าคอนโทรลเลอร์ปัจจุบันของฉันมีเฉพาะมุมมองบนหน้าจอแบบเคลื่อนไหวเท่านั้น ฉันไม่เคยคิดว่าตัวควบคุมมุมมองอื่นอาจทำแอนิเมชั่นของตัวเอง   -  person Aaron Hayman    schedule 07.06.2012
comment
@ThomasCatterall ใช่ฉันคุ้นเคยกับปัญหา 'renderInContext' (และฉันชอบฟัง B&A ซึ่งมักจะมีชีวิตอยู่ :)) ที่จริงแล้ว ตอนนั้นทำให้ฉันต้องซื้อ iPad 3 เพื่อทดสอบ ซึ่งกลายเป็นสิ่งจำเป็น ดีใจที่ได้ทำ ฉันต้องใช้โค้ดจำนวนมากที่ใช้ 'renderInContext' อีกครั้ง โชคดีที่นั่นไม่ใช่ปัญหาในกรณีนี้ ฉันพูดว่า 'โชคดี' เพราะทุกครั้งที่ฉันต้องแทนที่ 'renderInContext' ต้องใช้โค้ดจำนวนมากในการแก้ไข   -  person Aaron Hayman    schedule 07.06.2012
comment
เป็นเรื่องที่น่ารู้! ดีใจที่คุณจัดการได้แล้ว!   -  person Swizzlr    schedule 07.06.2012


คำตอบ (1)


นั่นมันเร็วมาก @RobNapier ถูกต้องว่าเป็นปัญหาเรื่องเวลา ฉันแสดงความคิดเห็นเกี่ยวกับแอนิเมชันของฉันและว้าว มีมุมมองอื่นๆ อีกมากมายที่เคลื่อนไหวอยู่ข้างหลังนั้น! แม้ว่าฉันจะสร้างภาพเคลื่อนไหวเฉพาะมุมมองบนหน้าจออย่างชัดเจน แต่ก็มี ViewController อีกตัวที่ได้รับเหตุการณ์การหมุนเวียนเบื้องหลังมุมมองของฉันโดยที่ฉัน... เอ่อ... ไม่รู้เหรอ? ฉันหมายถึงฉันควรจะรู้ใช่ไหม? ฉันเขียนโค้ด ตอนแรกฉันไม่รู้เพราะชุดมุมมองของฉันครอบคลุมทั้งหน้าจอ น่าเสียดายที่เรื่องนี้จะต้องมีการเขียนใหม่เป็นจำนวนมาก ฉันใช้ Custom Container Controllers และตอนนี้ฉันเห็นว่าจำเป็นต้องพิจารณาการใช้งานอีกครั้ง สิ่งต่างๆ มากมายได้รับการหมุนเวียน/เคลื่อนไหวโดยไม่จำเป็น แต่ว้าว...นั่นตอบโจทย์ด้านประสิทธิภาพมากมาย....

อัปเดต

ดังนั้นฉันจึงคิดว่าปัญหาที่ฉันเผชิญอยู่นั้นเกี่ยวข้องกับการดูพิเศษที่เคลื่อนไหวโดยตัวควบคุมมุมมองอื่น อย่างไรก็ตาม แม้ว่าสิ่งนี้จะเป็นความจริงในทางเทคนิค แต่ก็ไม่เป็นความจริงอย่างที่ฉันคิดหรือในแบบที่ฉันคิด ฉันแน่ใจอย่างแน่นอนว่าไม่มีมุมมองอื่นใดที่เคลื่อนไหวได้โดยการลบลำดับชั้นของรูทวิวทั้งหมดออกจากหน้าต่างและแทนที่ด้วยเฉพาะตัวควบคุมมุมมองที่ฉันต้องการหมุน สิ่งนี้ช่วยได้อย่างแน่นอน แต่ก็ไม่ได้ทั้งหมด จริงๆ แล้ว มันแค่ 'ลดแถบลง' เพื่อที่ฉันจะมีโอกาสได้รับข้อผิดพลาด 'wait_fences' น้อยลง ฉันยังคงค้นพบว่าฉันได้รับข้อผิดพลาดในบางสถานการณ์

ฉันเชื่อว่าปัญหาที่ฉันมีคือการใช้ UIScrollView การใช้งานของฉันมีจำนวนการดูย่อยที่แตกต่างกันซึ่งจัดการได้ มุมมองเฉพาะคือการใช้งาน UIPickerView ที่ฉันกำหนดเอง ดังนั้นอย่างที่คุณสามารถจินตนาการได้ จำนวนการดูที่จัดการอาจมีขนาดใหญ่มาก ฉันค้นพบว่าหากการดูย่อยเหล่านั้นมากเกินไป ฉันเริ่มได้รับข้อผิดพลาด 'wait_fences'

ปรากฏว่า: หาก UIScollView เป็นภาพเคลื่อนไหว มันจะทำให้การดูย่อยทั้งหมดเคลื่อนไหว แม้ว่าการดูย่อยเหล่านั้นจะไม่อยู่บนหน้าจอก็ตาม นี่เป็นสิ่งสำคัญ ฉันค่อนข้างสงสัยว่าผู้คนจำนวนมากที่กำลังดิ้นรนกับข้อผิดพลาดนี้อาจไม่ทราบเรื่องนี้ การดูย่อยนอกจอแต่ละรายการกำลังผลักดันให้คุณเข้าใกล้ข้อผิดพลาด 'wait_fences' มากขึ้นเรื่อยๆ วิธีแก้ปัญหาในกรณีของฉันคือ "ง่าย": ฉันจะแปลง UIScrollView เป็น UITableView นั่นหมายถึงการเขียนโค้ดใหม่จำนวนมาก แต่อย่างน้อยฉันก็รู้ว่าการดูย่อยนอกจอจะถูกลบออกจากหน้าจอ จึงไม่เคลื่อนไหว

ฉันยังสังเกตเห็นอย่างอื่นด้วย: Core-Graphic Gradients โจมตีคุณอย่างหนัก ฉันสามารถทำให้มุมมองนอกจอเคลื่อนไหวได้มากขึ้นหากไม่ใช้การไล่ระดับสี แน่นอนว่าฉันชอบการไล่ระดับสีและฉันไม่เต็มใจที่จะยอมแพ้ (ซึ่งเป็นเหตุผลว่าทำไมฉันถึงเขียน PickerView ใหม่) แต่มันก็น่าสนใจและสำคัญที่ควรทราบ

อัปเดต 2

เขียน UIScrollView ของฉันใหม่เป็น tableView เสร็จแล้วและดูเหมือนว่าจะได้ผลแล้ว ฉันไม่กระตุกและไม่มีข้อผิดพลาด wait_fences เมื่อหมุนหน้าจอ

อัปเดต 2

ใช่แล้ว การระบุข้อผิดพลาด wait_fences บน iPad 3 นั้นง่ายกว่า iPad/iPhone อื่นๆ มาก ฉันได้อ่านโค้ดทั้งหมดจนแน่ใจว่าฉันจะไม่ทำให้สิ่งใดก็ตามที่ไม่อยู่บนหน้าจอเคลื่อนไหว ดังนั้นปัญหาดังกล่าวจึงได้รับการแก้ไข ฉันยังคงได้รับข้อผิดพลาด wait_fences บน iPad 3 เมื่อฉันใช้กิจวัตรการวาดภาพที่ 'หนักมาก' สิ่งที่ฉันพบที่ทำให้ฉันโดน:

  1. การไล่ระดับสี: การไล่ระดับสีทำให้ CPU ทำงานบนหน้าจอเรตินาจริงๆ
  2. ความโปร่งใส: หากมุมมองของคุณไม่ทึบ CPU จะพยายามอย่างหนักเพื่อค้นหาพื้นที่โปร่งใสของมุมมอง
  3. สีโปร่งใส: ไม่เหมือนกับความโปร่งใสของมุมมอง นี่คือการวางชั้นสี/การไล่ระดับสีโปร่งใสไว้ด้านบนเพื่อให้ได้ 'เอฟเฟกต์' เช่น ความเงา หรือไฮไลท์อะไรก็ได้
  4. พื้นผิว: ฉันพบว่าการใช้พื้นผิวทำให้มีแนวโน้มที่จะเกิดข้อผิดพลาด wait_fences มากขึ้นเล็กน้อย แต่ก็ไม่มีอะไรที่ใกล้เคียงกับการไล่ระดับสี/ความโปร่งใส
person Aaron Hayman    schedule 07.06.2012