Это нормально, доступ к [UIApplication sharedApplication] из фонового потока? - PullRequest
1 голос
/ 11 февраля 2020

При работе с Objective-C мне нужно получить статус protectedDataAvailable, возможно, внутри некоторых фоновых потоков.

- (BOOL) isProtected {
    BOOL protectedDataAvailable = [[UIApplication sharedApplication] isProtectedDataAvailable];
    return protectedDataAvailable;
}

Когда я получаю доступ к [UIApplication sharedApplication], я подозреваю, что блок кода должен работать в основной очереди. Как я могу это сделать?

Я думал изменить его следующим образом:

- (BOOL) isProtected {

    BOOL protectedDataAvailable = NO;

    dispatch_sync(dispatch_get_main_queue(), ^{
        protectedDataAvailable = [[UIApplication sharedApplication] isProtectedDataAvailable];
    });

    return protectedDataAvailable;
}

Вопрос 1: Должен ли код выполняться внутри главная очередь / поток пользовательского интерфейса?

Вопрос 2: Если да, разрешит ли мой измененный код проблему? или есть какой-нибудь лучший подход?

Причина, по которой я задаю этот вопрос, заключается в том, что даже если я получаю синхронный доступ к UIApplication в главной очереди , когда блок вызывается из main thread это становится кр sh. Как я могу справиться с этой проблемой?

1 Ответ

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

Вопрос 1: должен ли код выполняться в главной очереди / потоке пользовательского интерфейса?

Определенно, да, потому что, если вы запустите приложение с помощью средства проверки основного потока в Xcode, выделите вызовы UIApplication sharedApplication как проблемы при доступе из фонового потока

Вопрос 2. Если да, разрешит ли мой измененный код проблему?

Если вы не позвоните isProtected из основного нить да.

или есть какой-нибудь лучший подход?

Я бы придерживался чего-то такого:

- (BOOL)isProtected
{
    __block BOOL protectedDataAvailable = NO;

    if ([NSThread isMainThread])
    {
        protectedDataAvailable = [[UIApplication sharedApplication] isProtectedDataAvailable];
    }
    else
    {
        dispatch_sync(dispatch_get_main_queue(), ^{

            protectedDataAvailable = [[UIApplication sharedApplication] isProtectedDataAvailable];
        });
    }

    return protectedDataAvailable;
}

Как указал Алехандро Иван в В комментарии вместо семафора можно прибегнуть к простому dispatch_sync

...