I am posting entries from a persistent core data store asynchronously to a web server. I would like to delete each associated managed object after a successful post.
My problem is that I am concurrently populating the store and making posts so I can't do a serial post / delete operation. Is there a way to mark an object for deletion until it's associated connectionDidFinishLoading
call has been made, then delete it?
I am also assuming that by using asynchronous NSURLRequests
, the application spawns multiple NSUR开发者_如何学运维LConnections
and runs them concurrently. Am I wrong in this assumption?
(Update) Thanks to Uberhamster's advice I tried to use delegates but I am failing. This is how I am going about this problem.I have declared a protocol in the class that handles the posts because that is where connectionDidFinishLoading
lives.
@protocol postDelegate
@optional
- (void)postCompleted;
@end
@interface makePosts : NSObject {
//...
id <postsDelegate> delegate;
}
@property (nonatomic, assign) id <postsDelegate> delegate;
//...
@end
@implementation makePosts
@synthesize delegate;
//...
- (void) connectionDidFinishLoading {
[delegate postCompleted];
}
//...
@end
And in the class that grabs data from the persistent store and spawns NSURLConnections
this is what I'm doing:
@interface myClass <postsDelegate>
//...
makePosts* makePostsObject;
@end
@implementation myClass
- (void) batchPost {
//...
for(NSManagedObject* obj in items) {
makePostsObject = [[makePosts alloc] init];
makePostsObject.delegate = self;
[makePostsObject setEntryName:[obj valueForKey:@"name"]]; // set reference here
NSString* post_data = [NSString stringWithString:[self createXMLPost:obj]];
[makePostsObject postdata:[obj valueForKey:@"name"]];
[makePostsObject release];
}
- (void) postCompleted
{
NSLog(@"posted entry for: %@", makePostsObject.entryName);
}
@end
I think what I am doing wrong is making myClass
the delegate? postCompleted
is called for every post that I make, but the reference each time is for the last post. Is there a way to get back the delegate from the callback function?
First, Classes should start with a capital letter. Starting them with a lowercase letter makes them hard to read. Second, @Uberhamster was suggesting you implement a NSURLConnection
delegate as follows:
@interface MyUploadDelegate : NSObject
@property (nonatomic, retain) NSManagedObject *postObject;
@end
@implementation MyUploadDelegate
@synthesize postObject;
- (void)dealloc
{
[postObject release], postObject = nil;
[super dealloc];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
//Connection is done, delete the object
[[[self postObject] managedObjectContext] deleteObject:[self postObject]];
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
//Deal with the error
}
@end
Then your code simply needs to do:
for (NSManagedObject *postObject in items) {
MyUploadDelegate *delegate = [[MyUploadDelegate alloc] init];
[delegate setPostObject:postObject];
NSURLRequest *request = ...;
[NSURLConnection connectionWithRequest:request delegate:delegate];
}
You should also have some retention of the delegates so that you can keep track of them and clean them up (the example code above leaks delegates).
You could instantiate one delegate object per every NSURLRequest that you fire, and that delegate object could have a reference to the core data item being processed. After that you could just delete the corresponding core data object from the store in the callback, and everything should be dandy.
(In response to your last paragraph I believe you are correct in that assumption)
精彩评论