Firebase crashlytics сообщает о множестве обнаруженных сбоев в моем приложении - PullRequest
0 голосов
/ 11 февраля 2020

Ниже приведен мой код

    func getImageFrom(_ asset: PHAsset, completion: @escaping (UIImage) -> Void) {
        var thumbnail = UIImage()
        let imageManager = PHCachingImageManager()
        let options = PHImageRequestOptions()
        options.version = .current
        let size = CGSize(width: 150.0, height: 150.0)

        imageManager.requestImage(for: asset, targetSize: size, contentMode: .aspectFill, 
        options: nil) { (image, info) in
            guard let img = image else { return }
            thumbnail = img
        }
        completion(thumbnail)
    }

Я использую эту функцию для получения изображения из PHAsset.

некоторое время, когда о sh сообщается в thumbnail = img или в completion(thumbnail).

с помощью этой функции в блоке кода ниже

func getImageDataAndFindDupImages() {
   var i = 0
   var similarImages = [OSTuple<NSString, NSString>]()
   similarImages = OSImageHashing.sharedInstance().similarImages(with: .high) { () -> OSTuple<NSString, NSData>? in
       #if DEBUG
       print(i)
       #endif
       var tuple = OSTuple<NSString, NSData>()
       if self.tempArrAssets.count > 0 {
           DispatchQueue.main.async {
               self.lblNumberOfPhoto.text = R.string.localizable.scanning_photos_number("\(i+1)", "\(self.arrPhotoAssets.count)")
           }
           if !self.tempArrAssets.isEmpty {
               let tempArrAsset = self.tempArrAssets.removeFirst()
               self.getImageFrom(tempArrAsset) { (imageAsset) in
                   self.arrImageFromAsset.append(imageAsset)
                   if let imgData = imageAsset.pngData() {
                       tuple = (OSTuple<NSString, NSData>(first: NSString(string: "\(i)"), andSecond: imgData as NSData))
                   }
               }
               i += 1
               return tuple
           } else {
               return nil
           }
       } else {
           return nil
       }
   }
   print("To make dup tuples:", Date().timeIntervalSince(self.date))
}

Я использую getImageFrom в getImageDataAndFindDupImages

Это журнал для cra sh

Crashed: com.apple.mobileslideshow.accessCallbacks
0  libobjc.A.dylib                0x18a874020 objc_retain + 16
1  Duplicate Cleaner              0x1001f0e80 closure #1 in DuplicatePhotoFinderVC.getImageDataAndFindDupImages() + 519 (DuplicatePhotoFinderVC.swift:519)
2  Duplicate Cleaner              0x1001f16a4 thunk for @escaping @callee_guaranteed () -> (@owned OSTuple<NSString, NSData>?) + 4338357924 (<compiler-generated>:4338357924)
3  CocoaImageHashing              0x1004f3514 -[OSSimilaritySearch similarImagesWithProvider:withHashDistanceThreshold:forImageStreamHandler:forResultHandler:] + 46 (OSSimilaritySearch.m:46)
4  CocoaImageHashing              0x1004f3924 -[OSSimilaritySearch similarImagesWithProvider:withHashDistanceThreshold:forImageStreamHandler:] + 95 (OSSimilaritySearch.m:95)
5  CocoaImageHashing              0x1004f28d0 -[OSImageHashing similarImagesWithProvider:withHashDistanceThreshold:forImageStreamHandler:] + 222 (OSImageHashing.m:222)
6  CocoaImageHashing              0x1004f27b0 -[OSImageHashing similarImagesWithHashingQuality:withHashDistanceThreshold:forImageStreamHandler:] + 201 (OSImageHashing.m:201)
7  CocoaImageHashing              0x1004f2734 -[OSImageHashing similarImagesWithHashingQuality:forImageStreamHandler:] + 190 (OSImageHashing.m:190)
8  Duplicate Cleaner              0x1001ee63c DuplicatePhotoFinderVC.getImageDataAndFindDupImages() + 316 (DuplicatePhotoFinderVC.swift:316)
9  Duplicate Cleaner              0x1001ee434 DuplicatePhotoFinderVC.fetchPhotosandCheckforDuplicate() + 146 (DuplicatePhotoFinderVC.swift:146)
10 Duplicate Cleaner              0x1001eea1c closure #1 in DuplicatePhotoFinderVC.checkForPermissionAndScanPhotos() + 162 (DuplicatePhotoFinderVC.swift:162)
11 Duplicate Cleaner              0x10021bdec thunk for @escaping @callee_guaranteed (@unowned PHAuthorizationStatus) -> () + 4338531820 (<compiler-generated>:4338531820)
12 Photos                         0x195ff9098 __39+[PHPhotoLibrary requestAuthorization:]_block_invoke + 64
13 AssetsLibraryServices          0x19f048edc __79-[PLPrivacy _isPhotosAccessAllowedWithScope:forceHandler:accessAllowedHandler:]_block_invoke.14 + 520
14 AssetsLibraryServices          0x19f01486c __pl_dispatch_async_block_invoke + 36
15 libdispatch.dylib              0x18a7fe610 _dispatch_call_block_and_release + 24
16 libdispatch.dylib              0x18a7ff184 _dispatch_client_callout + 16
17 libdispatch.dylib              0x18a7ab404 _dispatch_lane_serial_drain$VARIANT$mp + 608
18 libdispatch.dylib              0x18a7abdf8 _dispatch_lane_invoke$VARIANT$mp + 420
19 libdispatch.dylib              0x18a7b5314 _dispatch_workloop_worker_thread + 588
20 libsystem_pthread.dylib        0x18a84eb88 _pthread_wqthread + 276
21 libsystem_pthread.dylib        0x18a851760 start_wqthread + 8

Я не могу понять, почему у меня такие сбои. Если у вас есть какие-либо знания, пожалуйста, ведите меня.

1 Ответ

1 голос
/ 12 февраля 2020

Вы передаете nil в параметры в imageManager.requestImage(for:targetSize: contentMode:options:). Если вы передадите nil в качестве опций, метод вызовет блок завершения асинхронно. Таким образом, есть вероятность, что к тому времени, когда ваш блок завершения будет вызван, метод getImageFrom(: completion:) завершился, а локальная переменная thumbnail была уничтожена (я не говорю об уничтожении объекта UIImage, но о переменной, которая содержит адрес UIImage сам). Тогда попытка установить миниатюру миниатюры, которой больше нет в стеке, внутри блока может быть причиной того, что существует cra sh.

Для решения вашей проблемы Создайте экземпляр PHImageRequestOptions, установите его isSynchronous свойство для true , как это.

let options = PHImageRequestOptions()
options.isSynchronous = true

Теперь передайте этот options в качестве параметра imageManager.requestImage(for:targetSize: contentMode:options:)

В результате ваш imageManager.requestImage(for:targetSize: contentMode:options:) будет вызывать блок синхронно, т.е. перед выходом из метода getImageFrom(: completion:), поэтому переменная thumbnail все еще жива в стеке, который будет использоваться.

В надежде решить эту проблему.

PS : Будьте осторожны, вы вызываете метод getImageFrom(: completion:) в фоновом потоке, иначе ваш основной поток будет заморожен

...