-app hat serielle Warteschlange für NSURLConnection läuftWenn ich Realm hinzufügen dann sperrt sie CFRunLoopRun und meine Warteschlange für NSURLConnection
-app zu connectionDidFinishLoading Ereignis abonniert
-App macht einfach ‚Ping‘ an Ort und läuft CFRunLoopRun in der Warteschlange Ereignisse aktivieren
-app schließt Verbindung nach connectionDidFinishLoading Ereignis empfängt, auf CFRunLoopRun Ausfahrt protokollieren wir es und nach dem Austritt aus der Warteschlange Aufgabe noch eine weitere Aufgabe wird Schlitz erhalten für die Ausführung
-aber wenn wir Realm hinzufügen dann CFRunLoopRun läuft auf unbestimmte Zeit und jetzt unsere Warteschlange
gesperrt istIch öffnete Ticket https://github.com/realm/realm-cocoa/issues/4737 auch
#import "Realm/Realm.h"
@interface ViewController() <NSURLConnectionDataDelegate>
@end
@implementation ViewController {
dispatch_queue_t my_queue;
NSURLConnection *_connection;
}
- (void)viewDidLoad {
[super viewDidLoad];
my_queue = dispatch_queue_create("my queue", NULL);
dispatch_async(my_queue, ^{
[RLMRealm defaultRealm]; // (1) // comment to make it running
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
_connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
CFRunLoopRun(); // (2) infinite loop inside ios so (3) and (4) as result never been called
NSLog(@"done"); // (3)
});
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
dispatch_async(my_queue, ^{
NSLog(@"test"); // (4) // never been called when realm is used in the same queue
});
_connection = nil; // (5) // without (1) this line stops runloop so (2) and (3) will be called
}
Warum erwarten Sie, dass der Aufruf 'CFRunLoopRun()' zurückgibt? Sie rufen nicht 'CFRunLoopStop()' auf, sodass der Runloop ausgeführt wird, bis alle Quellen entfernt wurden. Unter der Annahme, dass nichts anderes verwendet wird, ist die Runloop sehr zerbrechlich. Ich würde auch empfehlen, keinen Runloop auf einem Thread auszuführen, den Sie nicht besitzen, insbesondere Dispatch Queues. Es gibt eine beschränkte Anzahl von Threads, die Service-Dispatch-Warteschlangen so tun, dass sie für einen unbestimmten Zeitraum blockiert werden, z. B. das Starten eines Runloops, das auf den Abschluss von Netzwerkoperationen wartet. Dies kann dazu führen, dass Dispatchwarteschlangen verhungern und möglicherweise Deadlocks verursachen. – bdash