iphone Este aplicativo está modificando o mecanismo de autolayout de um thread de segundo plano, o que pode levar à corrupção do mecanismo e a falhas estranhas




ios9 xcode7-beta4 (5)

Você tem código que atualiza o layout da interface do usuário de um thread de segundo plano. Alterar a fila de operações na qual você executa seu código não precisa ser explícito. Por exemplo, NSURLSession.shared () não usa a fila principal ao fazer novas solicitações. Para garantir que seu código seja executado no thread principal, estou usando o método estático mainQueue () do NSOperationQueue.

Rápido:

NSOperationQueue.mainQueue().addOperationWithBlock(){
    //Do UI stuff here
}

Obj-C:

[NSOperationQueue mainQueue] addOperationWithBlock:^{
    //Do UI stuff here
}];

Eu recebo este log no console quando estou executando meu aplicativo no simulador. Não vi isso no iOS 8. Não tenho certeza do que está causando isso. Alguém mais se deparou com o mesmo problema e, em caso afirmativo, como foi corrigido? ou há alguma ajuda que alguém possa fornecer em relação a isso?


Swift 3.0

DispatchQueue.main.async {
}

Não altere a interface do usuário de nada, mas o segmento principal. Embora pareça funcionar em alguns sistemas operacionais ou dispositivos, e não em outros, é obrigado a tornar seu aplicativo instável e travar de forma imprevisível.

Se você precisar responder a uma notificação, o que pode acontecer em segundo plano, assegure-se de que a chamada do UIKit ocorra no thread principal .

Você tem pelo menos estas duas opções:

Envio assíncrono

Use o GCD (Grand Central Dispatch) se o seu observador puder ser notificado em qualquer tópico. Você pode ouvir e trabalhar a partir de qualquer thread e encapsular as alterações da interface do usuário em um dispatch_async :

dispatch_async(dispatch_get_main_queue()) {
    // Do UI stuff here
}

Quando usar o GCD ? Quando você não controla quem envia a notificação. Pode ser o sistema operacional, um Cocoapod, bibliotecas embutidas, etc. O uso do GCD irá despertar a qualquer momento, a qualquer momento. Desvantagem: Você se encontra reprogramando o trabalho.

Ouça no tópico principal

Convenientemente, você pode especificar em qual encadeamento você deseja que o observador seja notificado, no momento em que você está se registrando para notificações, usando o parâmetro de queue :

addObserverForName:@"notification"
    object:nil
    queue:[NSOperationQueue mainQueue]
    usingBlock:^(NSNotification *note){
        // Do UI stuff here
    }

Quando observar no thread principal ? Quando você está registrando e registrado. No momento em que você responde à notificação, você já está onde precisa estar.

Post Notification On Main Thread

[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];

Solução híbrida que não garante que o observador seja invocado apenas a partir do referido método. Permite um observador mais leve, ao custo de um design menos robusto. Apenas mencionado aqui como uma solução que você provavelmente deve evitar .


Deve tentar Breakpoint Simbólico para detectar o problema: -

Símbolo:

[UIView layoutIfNeeded]`

Condição:

!(BOOL)[NSThread isMainThread]

Em seguida, coloque seu código de atualização da interface do usuário no segmento principal

DispatchQueue.main.async {}

O mesmo problema aconteceu no meu caso, eu tenho que mudar o código da seguinte maneira, então funciona bem. Em ViewDidLoad , chame esse método usando main thread ,

[self performSelectorOnMainThread:@selector(setUpTableRows) withObject:nil waitUntilDone:YES];






xcode7-beta4