Hanya di iPad 3 baru: wait_fences: gagal menerima balasan: 10004003

Jadi saya tahu ada banyak pertanyaan mengenai hal ini, tapi sejauh yang saya tahu ini adalah situasi yang unik jadi saya pikir saya akan mempostingnya. Semoga dapat menambah beberapa info yang pada akhirnya dapat memberikan kita jawaban mengapa hal ini terjadi pada kita. Saya mendapatkan pesan kesalahan: wait_fences: gagal menerima balasan: 10004003, saat perangkat saya berputar. Animasi pandangan saya dimulai dari:

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

Saya hanya mendapatkan kesalahan pada iPad 3 baru. Saya telah menggunakan program yang sama persis pada iPad asli dan iPhone serendah 3GS. Mereka semua tidak mendapatkan kesalahan wait_fences dan semuanya berputar lebih cepat daripada iPad 3.

Saya menggunakan Core Graphics hampir secara eksklusif untuk menggambar tampilan. Saya juga memastikan gambar tersebut digambar ulang dan diubah ukurannya sehingga saya tidak mendapatkan tampilan yang kacau. Jika saya menonaktifkan gambar ulang saat mengubah ukuran, saya tidak mendapatkan kesalahan ini (tetapi saya mendapatkan tampilan yang melebar). Jika saya menonaktifkan gambar grafik inti sama sekali, saya tidak mendapatkan kesalahan (tetapi, tentu saja, saya mendapatkan tampilan hitam).

Saya menggunakan Time Profiler dan menemukan bahwa hangup terutama terjadi pada gradien gambar: masukkan deskripsi gambar di sini

Saya telah mengubah kode untuk mengisi daripada menggambar gradien dan itu meringankan masalah. Saya akan mengatakan bahwa gradien adalah masalahnya kecuali saya melakukan animasi ini dalam situasi lain (selain sebagai respons terhadap rotasi) dan itu berfungsi dengan baik.

Saya juga ingin mencatat bahwa saya memberikan perhatian khusus untuk memastikan saya hanya menganimasikan tampilan yang benar-benar ada di layar. Saya tahu bahwa menganimasikan tampilan di luar layar terkadang dapat menyebabkan kesalahan ini terjadi.

Saya belum menyertakan kode animasinya

Adakah gagasan mengapa hal ini terjadi? Apalagi ini hanya terjadi di iPad 3?

Bagi yang bertanya, inilah kode yang menjalankan animasinya. Biasanya akan dibungkus dalam Blok Animasi UIView.

- (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 sumber
comment
Fakta bahwa ini hanya terjadi di iPad 3 sebagian besar menunjukkan bahwa ini adalah masalah waktu yang dipicu oleh iPad 3 dengan cukup cepat. Hal ini tidak secara khusus menunjukkan bahwa hal tersebut benar pada platform lain; hanya saja Anda beruntung di platform lain. Jawaban lain, khususnya seputar ketidakcocokan animasi awal/akhir, atau animasi saat di luar layar, kemungkinan masih dapat diterapkan.   -  person Rob Napier    schedule 07.06.2012
comment
Saya tidak dapat mengatakan seberapa relevan hal ini karena saya memiliki sedikit pengalaman dengan CoreAnimation, tetapi Marco Arment membahas masalah khusus iPad 3 dengan CA renderInContext yang disebabkan oleh perangkat keras grafis yang funky di dalamnya. Diskusinya dapat ditemukan di podcastnya, Build and Analyze ep 72, dimulai pada 56:20. Hasilnya adalah iPad lebih lambat, menurut saya. Mungkin ada sesuatu yang bisa diperoleh?   -  person Swizzlr    schedule 07.06.2012
comment
@RobNapier Ya, akhirnya Anda benar. Saya menghabiskan begitu banyak waktu untuk memastikan pengontrol saya saat ini hanya menganimasikan tampilan di layar. Saya tidak pernah mempertimbangkan bahwa pengontrol tampilan lain mungkin melakukan animasinya sendiri.   -  person Aaron Hayman    schedule 07.06.2012
comment
@ThomasCatterall Ya, saya akrab dengan masalah 'renderInContext' (dan saya suka mendengarkan B&A, biasanya live :)). Faktanya, episode tersebut mendorong saya untuk membeli iPad 3 untuk diuji, yang ternyata sangat penting. Senang melakukannya, saya harus mengimplementasikan kembali banyak kode yang menggunakan 'renderInContext'. Untungnya, bukan itu masalahnya dalam kasus ini. Saya mengatakan 'untungnya' karena setiap kejadian saya harus mengganti 'renderInContext' memerlukan banyak kode untuk memperbaikinya.   -  person Aaron Hayman    schedule 07.06.2012
comment
Ya, senang mengetahuinya! Senang Anda menyelesaikannya!   -  person Swizzlr    schedule 07.06.2012


Jawaban (1)


Ya, itu cepat. @RobNapier benar karena masalah waktu. Saya mengomentari animasi saya dan wow ada banyak tampilan lain yang dianimasikan di belakang sana! Meskipun saya secara eksplisit hanya menganimasikan tampilan di layar, ada ViewController lain yang menerima peristiwa rotasi di belakang tampilan saya tanpa... uh... sepengetahuan saya? Maksudku, aku harusnya tahu kan? Saya menulis kodenya. Awalnya saya tidak menyadarinya karena kumpulan pandangan saya menutupi seluruh layar. Sayangnya hal ini memerlukan banyak penulisan ulang. Saya menggunakan Pengontrol Kontainer Khusus dan sekarang saya merasa perlu mempertimbangkan kembali penerapan saya. Banyak hal yang diputar/dianimasikan secara tidak perlu. Tapi wow...itu menjawab banyak pertanyaan kinerja....

Pembaruan

Jadi saya berpikir bahwa masalah yang saya hadapi ada hubungannya dengan tampilan tambahan yang dianimasikan oleh pengontrol tampilan lainnya. Namun, meskipun secara teknis hal ini benar, namun tidak sebenar yang saya kira atau seperti yang saya pikirkan. Saya benar-benar memastikan bahwa tidak ada tampilan lain yang dianimasikan dengan menghapus seluruh hierarki tampilan root dari jendela dan menggantinya hanya dengan pengontrol tampilan yang ingin saya putar. Hal ini jelas membantu, namun tidak sepenuhnya. Sungguh, ini hanya 'menurunkan standar' sehingga kecil kemungkinan saya mendapatkan kesalahan 'wait_fences'. Saya masih menemukan bahwa saya mendapatkan kesalahan meskipun dalam situasi tertentu.

Saya yakin masalah yang saya alami adalah penggunaan UIScrollView. Implementasi saya memiliki sejumlah variabel subview yang dikelolanya. Tampilan spesifiknya adalah implementasi UIPickerView kustom saya sendiri, sehingga seperti yang dapat Anda bayangkan, jumlah tampilan yang dikelolanya bisa menjadi cukup besar. Saya menemukan bahwa jika subview tersebut menjadi terlalu banyak, saya mulai mendapatkan kesalahan 'wait_fences'.

Jadi terlihat seperti ini: Jika UIScollView dianimasikan, maka semua subtampilannya akan dianimasikan, meskipun subtampilannya tidak ada di layar. Ini penting. Saya curiga banyak orang yang mengalami kesalahan ini mungkin tidak menyadari hal ini. Masing-masing subview di luar layar mendorong Anda semakin dekat untuk mencapai kesalahan 'wait_fences'. Solusi dalam kasus saya adalah "sederhana": Saya akan mengubah UIScrollView saya menjadi UITableView. Itu berarti menulis ulang banyak kode, tapi setidaknya saya tahu bahwa subview di luar layar akan dihapus dari layar dan karenanya tidak dianimasikan.

Saya juga mencatat hal lain: Core-Graphic Gradients sangat memukul Anda. Saya dapat menganimasikan lebih banyak tampilan di luar layar jika tidak menggunakan gradien. Tentu saja, saya menyukai gradien dan saya tidak mau melepaskannya (itulah sebabnya saya menulis ulang PickerView saya) tetapi ini menarik dan penting untuk diperhatikan.

Pembaruan 2

Selesai menulis ulang UIScrollView saya sebagai tableView dan sepertinya berhasil. Saya tidak mengalami lag dan tidak ada kesalahan wait_fences saat memutar layar.

Pembaruan 2

Jadi ya, jauh lebih mudah untuk menemukan kesalahan wait_fences di iPad 3 dibandingkan iPad/iPhone lainnya. Saya telah memeriksa semua kode saya untuk memastikan saya tidak pernah menganimasikan apa pun yang tidak ada di layar, sehingga masalah tersebut teratasi. Saya masih mendapatkan kesalahan wait_fences di iPad 3 ketika saya menggunakan rutinitas menggambar yang 'berat'. Hal-hal yang saya temukan yang membuat saya berhasil:

  1. Gradien: gradien benar-benar membuat CPU bekerja pada layar retina.
  2. Transparansi: jika tampilan Anda tidak buram, CPU bekerja keras untuk mengetahui area transparan pada tampilan.
  3. Warna Transparan: tidak sama dengan transparansi tampilan. Ini adalah melapisi warna/gradien transparan di atas satu sama lain untuk mendapatkan 'efek', seperti kilap, menonjolkan apa pun.
  4. Tekstur: Menurut saya penggunaan tekstur membuatnya lebih mungkin untuk mencapai kesalahan wait_fences, tetapi tidak seperti yang dilakukan gradien/transparansi.
person Aaron Hayman    schedule 07.06.2012