Делегат не работает (связан с Restkit?)

Я только начинаю работать с Objective C и Restkit.

Я создал образец приложения и добавил RKRequestDelegate в файл MyAppDelegate.

@interface MyAppDelegate : NSObject <UIApplicationDelegate, RKRequestDelegate> {…

и добавил

  RKClient* client = [RKClient clientWithBaseURL:@"http://localhost:3000"]; 
   NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);
   [client get:@"/titles.json" delegate:self];

в MyAppDelegate.m в

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method

Я также добавил метод в MyAppDelegate.m

- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
    if ([request isGET]) {        
        NSLog (@"Retrieved : %@", [response bodyAsString]);
    }
 }

пока все работает хорошо, и я вижу результаты моего приложения Rails на выходе!!!

Поскольку эти вещи не принадлежат MyAppDelegate.m, я перемещаю их в свои модели. В моих Titles.h я добавил

@interface Titles : NSManagedObject <RKRequestDelegate> {

а в Titles.m добавил

+ (void) update {   
    [[RKClient sharedClient] get:@"/titles.json" delegate:self];
}

и

- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
    if ([request isGET]) {
        NSLog (@"Retrieved : %@", [response bodyAsString]);
    }
}

В моем MyAppDelegate.m я заменил:

 RKClient* client = [RKClient clientWithBaseURL:@"http://localhost:3000"]; 
   NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);
   [client get:@"/titles.json" delegate:self];

с участием

  RKClient* client = [RKClient clientWithBaseURL:@"http://localhost:3000"]; 
   NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);
  [Titles update];

когда я бегу сейчас, я не получаю никакого вывода. Я поставил несколько точек останова, одну в - (void)didFinishLoad:(RKResponse*)response в файле RKRequest и там тест if для:

if ([_delegate respondsToSelector:@selector(request:didLoadResponse:)]) {
        [_delegate request:self didLoadResponse:finalResponse];
    }

терпит неудачу, в то время как это удается в моей первой попытке (когда все находится в MyAppDelegate)

Я проверил переменную _delegate в отладчике, и она говорит: _delegate = MyAppDelegate в моей первой попытке и _delegate = Titles в моей второй попытке (как и должно быть)

Почему не работает responsesToSelector? (делегат правильный, и метод существует в заголовках)


person Glenn    schedule 09.09.2011    source источник


Ответы (1)


Ваша проблема в том, что вы пытаетесь установить класс в качестве делегата:

+ (void) update {   
  [[RKClient sharedClient] get:@"/titles.json" delegate:self];
}

self вот класс Titles.

Обратный вызов (как и ожидалось) является методом экземпляра:

- (void) request: (RKRequest *) request didLoadResponse: (RKResponse *) response {
  if ([request isGET]) {
    NSLog (@"Retrieved : %@", [response bodyAsString]);
  }
}

У вас должен быть какой-то класс модели «DataModel» (возможно, «SongList» или что-то еще, что имеет смысл). Часто это синглтон, поэтому у вас есть экземпляр +sharedModel. Этот экземпляр является делегатом для RKClient.

person Rob Napier    schedule 09.09.2011
comment
Большое спасибо, Роб, я провел небольшое тестирование, выполнив «обновление» метода экземпляра и создав объект Titles *title = [Titles alloc]; [обновление названия]; и это работает. Однако я не понимаю вашего объяснения класса DataModel. Можете ли вы уточнить. Заголовки моего класса - это NSManagedObject (с использованием основных данных), и в нем будут храниться все заголовки для разных альбомов. Причина, по которой я использовал метод класса, заключается в том, что создание объекта, как я сделал в своем тестировании, глупо и не является хорошим дизайном. - person Glenn; 09.09.2011
comment
Это странный дизайн. Почему у вас есть специальный NSManagedObject, который содержит свойства других объектов? Кажется, это борьба с Core Data. Я бы подумал, что у вас есть Collection или AlbumCollection, которые будут содержать Album объекты. И затем вы можете использовать [collection allTitles] для возврата заголовков, если вам это нужно в виде списка строк. - person Rob Napier; 09.09.2011
comment
Очевидно, мои объяснения были не очень ясны... У меня есть следующие классы: Исполнители (свойства: имя, имя_сцены, день рождения,...) и отношение has_and_belongs_to_many Альбомы, Альбомы (свойства: имя, год, обложка) has_many Titles . .. Все они являются NSManagedObjects. Я хотел, чтобы у каждого из них было обновление метода класса, которое я вызывал бы при старте приложения. Этот метод будет синхронизировать данные с приложением Rails. - person Glenn; 09.09.2011
comment
В ПОРЯДКЕ; так что название — это то, что наивный читатель (я) подумал бы о песне или треке :D Но очевидно, что в альбомах есть много вещей, которые не являются песнями, и трек, вероятно, просто показывает мой возраст, так что это имеет смысл. - person Rob Napier; 09.09.2011
comment
хе-хе Роб, я не являюсь носителем английского языка и, вероятно, также наивен, думаю, трек может быть лучшим описанием, я выбираю название как в названии песни (если это имеет смысл, это имеет смысл в нашем языке). Во всяком случае, я до сих пор не знаю, как решить эту проблему без метода класса... - person Glenn; 10.09.2011
comment
Переместите все обновления в CollectionManager singleton, отвечающий за управление обновлениями всего. Если вы хотите, чтобы они были отдельными, создайте синглтоны AlbumManager, TitleManager и ArtistManager, которые будут отвечать за все экземпляры этого класса. - person Rob Napier; 10.09.2011