Задача c помочь с пользовательскими делегатами и асинхронными данными - PullRequest
0 голосов
/ 07 ноября 2010

Я отправляю записи из постоянного хранилища основных данных асинхронно на веб-сервер. Я хотел бы удалить каждый связанный управляемый объект после успешной публикации.

Моя проблема в том, что я одновременно заполняю хранилище и делаю посты, поэтому я не могу выполнить последовательную операцию пост / удаление. Есть ли способ пометить объект для удаления, пока не будет выполнен связанный вызов connectionDidFinishLoading, а затем удалить его?

Я также предполагаю, что при использовании асинхронного NSURLRequests приложение порождает несколько NSURLConnections и запускает их одновременно. Я ошибаюсь в этом предположении?


(Обновление) Благодаря совету Uberhamster я пытался использовать делегатов, но у меня не получается. Вот как я решаю эту проблему. Я объявил протокол в классе, который обрабатывает сообщения, потому что именно там живет connectionDidFinishLoading.

@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

И в классе, который получает данные из постоянного хранилища и порождает NSURLConnections это то, что я делаю:

@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

Я думаю, что я неправильно делаю myClass делегатом? postCompleted вызывается для каждого сообщения, которое я делаю, но ссылка каждый раз для последнего сообщения. Есть ли способ вернуть делегата из функции обратного вызова?

Ответы [ 2 ]

2 голосов
/ 11 ноября 2010

Во-первых, классы должны начинаться с заглавной буквы.Начиная их со строчной буквы, их трудно читать.Во-вторых, @Uberhamster предлагал вам реализовать делегат NSURLConnection следующим образом:

@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

Тогда ваш код просто должен сделать:

for (NSManagedObject *postObject in items) {
  MyUploadDelegate *delegate = [[MyUploadDelegate alloc] init];
  [delegate setPostObject:postObject];

  NSURLRequest *request = ...;
  [NSURLConnection connectionWithRequest:request delegate:delegate];
}

У вас также должно быть некоторое сохранениеделегаты, чтобы вы могли отслеживать их и очищать их (в приведенном выше примере кода утечки делегатов).

1 голос
/ 09 ноября 2010

Вы можете создать экземпляр одного объекта делегата на каждый запускаемый вами NSURLRequest, и этот объект делегата может иметь ссылку на обрабатываемый элемент данных ядра.После этого вы можете просто удалить соответствующий объект базовых данных из хранилища в обратном вызове, и все должно быть прекрасно.

(В ответ на ваш последний абзац я верю, что вы правы в этом предположении)

...