简体   繁体   中英

Compiler error while declaring an array: compiler is unable to type-check … distinct sub-expressions

I'm using healthkit and getting the permision to read data. When asking for 5 data types it is fine. Although, when one more is added it gives me the error The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions . Here is the Code

let healthkitTypesToRead = NSSet(array: [
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.height) ?? "",
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMass) ?? "",
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate) ?? "",
            HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.sleepAnalysis) ?? "",
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bloodPressureDiastolic) ?? "",
            HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bloodPressureSystolic) ?? ""



            ]
        )

It's not clear why you've injected ?? "" ?? "" into this code. That appears to be meaningless (it says "if I can't add this quantityType, then add a string, which makes no sense). I think what you mean is "I just want these to be added if they're non-nil, and really they should be, but I don't want to add ! and crash if I'm wrong." If that's what you mean, then this is what you mean:

let healthkitTypesToRead = Set<HKObjectType>([
    .quantityType(forIdentifier: .height),
    .quantityType(forIdentifier: .bodyMass),
    .quantityType(forIdentifier: .heartRate),
    .categoryType(forIdentifier: .sleepAnalysis),
    .quantityType(forIdentifier: .bloodPressureDiastolic),
    .quantityType(forIdentifier: .bloodPressureSystolic),
    ].compactMap { $0 }
)

However, these are all compile-time constants. If any of them fail, that's really a programming mistake. That is a point where ! is appropriate, and so I would personally write it this way (but this is just a matter of opinion and style):

let healthkitTypesToRead = Set<HKObjectType>([
    .quantityType(forIdentifier: .height)!,
    .quantityType(forIdentifier: .bodyMass)!,
    .quantityType(forIdentifier: .heartRate)!,
    .categoryType(forIdentifier: .sleepAnalysis)!,
    .quantityType(forIdentifier: .bloodPressureDiastolic)!,
    .quantityType(forIdentifier: .bloodPressureSystolic)!,
    ]
)

Note I've replaced NSSet with Set . Unless you have a very strong reason, you should not use NSSet here.

Use:

   protocol HKCustomContainer: Hashable { }
extension HKCategoryTypeIdentifier: HKCustomContainer { }
extension HKQuantityTypeIdentifier: HKCustomContainer { }
let identifierArray: [HKCustomContainer] = [
    HKQuantityTypeIdentifier.height,
    HKQuantityTypeIdentifier.bodyMass,
    HKQuantityTypeIdentifier.heartRate,
    HKCategoryTypeIdentifier.sleepAnalysis,
    HKQuantityTypeIdentifier.bloodPressureDiastolic,
    HKQuantityTypeIdentifier.bloodPressureSystolic
]

let hkObjectTypeArray: [String] = identifierArray.compactMap {
    if let qt = $0 as? HKQuantityTypeIdentifier {
        return HKObjectType.quantityType(forIdentifier: qt) ?? ""
    } else if let ct = $0 as? HKCategoryTypeIdentifier {
        return HKObjectType.categoryType(forIdentifier: ct) ?? ""
    }
    return nil
}
print(Set(hkObjectTypeArray))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM