mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-24 04:46:01 +08:00
Migrate performSelectorOnMainThread and performSelectorInBackground invocations to GCD
This commit is contained in:
@@ -398,7 +398,7 @@ static RKManagedObjectStore *defaultObjectStore = nil;
|
||||
|
||||
// If we are a background Thread MOC, we need to inform the main thread on save
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(mergeChanges:)
|
||||
selector:@selector(managedObjectContextDidSaveNotification:)
|
||||
name:NSManagedObjectContextDidSaveNotification
|
||||
object:managedObjectContext];
|
||||
}
|
||||
@@ -406,18 +406,11 @@ static RKManagedObjectStore *defaultObjectStore = nil;
|
||||
return managedObjectContext;
|
||||
}
|
||||
|
||||
- (void)mergeChangesOnMainThreadWithNotification:(NSNotification *)notification
|
||||
- (void)managedObjectContextDidSaveNotification:(NSNotification *)notification
|
||||
{
|
||||
assert([NSThread isMainThread]);
|
||||
[self.primaryManagedObjectContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
|
||||
withObject:notification
|
||||
waitUntilDone:YES];
|
||||
}
|
||||
|
||||
- (void)mergeChanges:(NSNotification *)notification
|
||||
{
|
||||
// Merge changes into the main context on the main thread
|
||||
[self performSelectorOnMainThread:@selector(mergeChangesOnMainThreadWithNotification:) withObject:notification waitUntilDone:YES];
|
||||
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
|
||||
[self.primaryManagedObjectContext mergeChangesFromContextDidSaveNotification:notification];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@@ -133,10 +133,14 @@
|
||||
|
||||
- (void)invokeOnMainThread
|
||||
{
|
||||
[self retain];
|
||||
[self serializeManagedObjects];
|
||||
[self performSelectorOnMainThread:@selector(performInvocationOnMainThread) withObject:nil waitUntilDone:YES];
|
||||
[self release];
|
||||
if ([NSThread isMainThread]) {
|
||||
[self performInvocationOnMainThread];
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[self performInvocationOnMainThread];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#import "RKConfigurationDelegate.h"
|
||||
#import "RKRouter.h"
|
||||
|
||||
// Retrieves the dispatch queue for emitting network processing events
|
||||
dispatch_queue_t rk_get_network_processing_queue(void);
|
||||
|
||||
/**
|
||||
RKClient exposes the low level client interface for working with HTTP servers
|
||||
and RESTful services. It wraps the request/response cycle with a clean, simple
|
||||
@@ -82,6 +85,7 @@
|
||||
provided via the RKRequestSerializable protocol and is not specific to
|
||||
NSDictionary objects.
|
||||
|
||||
|
||||
### Sending Asynchronous Requests
|
||||
|
||||
A handful of methods are provided as a convenience to cover the common
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
static RKClient *sharedClient = nil;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// URL Conveniences functions
|
||||
// Conveniences functions
|
||||
|
||||
NSURL *RKMakeURL(NSString *resourcePath) {
|
||||
return [[RKClient sharedClient].baseURL URLByAppendingResourcePath:resourcePath];
|
||||
@@ -63,6 +63,17 @@ NSString *RKPathAppendQueryParams(NSString *resourcePath, NSDictionary *queryPar
|
||||
return [resourcePath stringByAppendingQueryParameters:queryParams];
|
||||
}
|
||||
|
||||
static dispatch_queue_t rk_network_processing_queue;
|
||||
dispatch_queue_t rk_get_network_processing_queue(void)
|
||||
{
|
||||
if (rk_network_processing_queue == NULL) {
|
||||
rk_network_processing_queue = dispatch_queue_create("org.restkit.network.processing-queue", 0);
|
||||
}
|
||||
|
||||
return rk_network_processing_queue;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface RKClient ()
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#import "RKParserRegistry.h"
|
||||
#import "RKRequestSerialization.h"
|
||||
|
||||
extern dispatch_queue_t rk_get_network_processing_queue(void);
|
||||
|
||||
NSString *RKRequestMethodNameFromType(RKRequestMethod method) {
|
||||
switch (method) {
|
||||
case RKRequestMethodGET:
|
||||
@@ -492,7 +494,11 @@ RKRequestMethod RKRequestMethodTypeFromName(NSString *methodName) {
|
||||
if ([self shouldLoadFromCache]) {
|
||||
RKResponse *response = [self loadResponseFromCache];
|
||||
self.loading = YES;
|
||||
[self performSelector:@selector(didFinishLoad:) withObject:response afterDelay:0];
|
||||
dispatch_async(rk_get_network_processing_queue(), ^{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[self didFinishLoad:response];
|
||||
});
|
||||
});
|
||||
} else if ([self shouldDispatchRequest]) {
|
||||
[self createTimeoutTimer];
|
||||
#if TARGET_OS_IPHONE
|
||||
@@ -548,7 +554,11 @@ RKRequestMethod RKRequestMethodTypeFromName(NSString *methodName) {
|
||||
errorMessage, NSLocalizedDescriptionKey,
|
||||
nil];
|
||||
NSError *error = [NSError errorWithDomain:RKErrorDomain code:RKRequestBaseURLOfflineError userInfo:userInfo];
|
||||
[self performSelector:@selector(didFailLoadWithError:) withObject:error afterDelay:0];
|
||||
dispatch_async(rk_get_network_processing_queue(), ^{
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
[self didFailLoadWithError:error];
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +281,9 @@ static const NSTimeInterval kFlushDelay = 0.3;
|
||||
// We always want to dispatch requests from the main thread so the current thread does not terminate
|
||||
// and cause us to lose the delegate callbacks
|
||||
if (! [NSThread isMainThread]) {
|
||||
[self performSelectorOnMainThread:@selector(loadNextInQueue) withObject:nil waitUntilDone:NO];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self loadNextInQueue];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -590,8 +592,9 @@ static NSInteger networkActivityCount;
|
||||
- (void)refreshActivityIndicator
|
||||
{
|
||||
if (![NSThread isMainThread]) {
|
||||
SEL sel_refresh = @selector(refreshActivityIndicator);
|
||||
[self performSelectorOnMainThread:sel_refresh withObject:nil waitUntilDone:NO];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self refreshActivityIndicator];
|
||||
});
|
||||
return;
|
||||
}
|
||||
BOOL active = (self.networkActivityCount > 0);
|
||||
|
||||
@@ -130,12 +130,13 @@
|
||||
self.loading = NO;
|
||||
self.loaded = successful;
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(objectLoaderDidFinishLoading:)]) {
|
||||
[(NSObject<RKObjectLoaderDelegate>*)self.delegate performSelectorOnMainThread:@selector(objectLoaderDidFinishLoading:)
|
||||
withObject:self waitUntilDone:YES];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if ([self.delegate respondsToSelector:@selector(objectLoaderDidFinishLoading:)]) {
|
||||
[(NSObject<RKObjectLoaderDelegate>*)self.delegate objectLoaderDidFinishLoading:self];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFinishLoadingNotification object:self];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidFinishLoadingNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
// Invoked on the main thread. Inform the delegate.
|
||||
@@ -185,7 +186,9 @@
|
||||
- (void)processMappingResult:(RKObjectMappingResult *)result
|
||||
{
|
||||
NSAssert(_sentSynchronously || ![NSThread isMainThread], @"Mapping result processing should occur on a background thread");
|
||||
[self performSelectorOnMainThread:@selector(informDelegateOfObjectLoadWithResultDictionary:) withObject:[result asDictionary] waitUntilDone:YES];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self informDelegateOfObjectLoadWithResultDictionary:[result asDictionary]];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Response Object Mapping
|
||||
@@ -472,10 +475,12 @@
|
||||
if (self.result) {
|
||||
[self processMappingResult:self.result];
|
||||
} else {
|
||||
[self performSelectorInBackground:@selector(didFailLoadWithError:) withObject:error];
|
||||
dispatch_async(rk_get_network_processing_queue(), ^{
|
||||
[self didFailLoadWithError:error];
|
||||
});
|
||||
}
|
||||
} else {
|
||||
[self performMappingInDispatchQueue];
|
||||
[self performMappingInOperationQueue];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user