Это один из моих первых попыток написать своих собственных делегатов.Я использую iOS5 Beta 7 и пишу свою делегатскую функцию.
Что нужно сделать, так это чтобы таблица (MyTableController
) загружала список телеканалов.Это словарь, содержащий ключ «логотип», который является URL-адресом логотипа изображения.Я создал свой класс с именем "Channel
" и мой делегат с именем "ChannelDelegate
".Теперь, когда моя таблица выполняет cellForRowAtIndexPath
, она инициирует мой класс Channel и вызывает функцию getChannelImageForChannelId:externalRefference:indexPath
.Пока все хорошо, теперь мой класс канала проверяет, существует ли файл локально, если нет, он загрузит его (используя ASIHttpRequest
).Кроме того, пока все хорошо.Теперь, когда ASIHttpRequest возвращается на requestDidFinish, он умирает после нескольких результатов.Я заметил, что файл действительно был загружен, потому что после нескольких попыток он работает как чудо, поэтому мой делегат, кажется, работает.
Это мой код:CellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CurrentChannelInfoCell";
CurrentChannelInfoCell *cell = (CurrentChannelInfoCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[CurrentChannelInfoCell class]])
{
cell = (CurrentChannelInfoCell *)currentObject;
break;
}
}
}
NSArray *keys = [self.content allKeys];
id channelId = [keys objectAtIndex:indexPath.row];
NSDictionary *channel = [self.content objectForKey:channelId];
int cId = [(NSString*)channelId intValue];
[cell.textLabel setText:[channel objectForKey:@"name"]];
[cell.channelImage setHidden:YES];
Channel *theChannel = [[Channel alloc] init];
[theChannel setDelegate:self];
[theChannel getChannelImageForChannelId:cId externalRefference:[channel objectForKey:@"logotype"] indexPath:indexPath];
return cell;
}
- (void)didRecieveImageForChannel:(NSString*)imagePath indexPath:(NSIndexPath*)indexPath
{
NSLog(@"Did recieve the it.!");
}
Мой делегат, ChannelDelegate.h
:
#import <Foundation/Foundation.h>
@class Channel;
@protocol ChannelDelegate <NSObject>
@optional
- (void)didRecieveImageForChannel:(NSString*)imagePath indexPath:(NSIndexPath*)indexPath;
@end
Channel.h
:
#import <Foundation/Foundation.h>
#import "ChannelDelegate.h"
#import "Reachability.h"
#import "ASIHTTPRequest.h"
#import "ASINetworkQueue.h"
#import "ASIFormDataRequest.h"
@interface Channel : NSOperation <NSObject, ASIHTTPRequestDelegate>
{
ASINetworkQueue *networkQueue;
// Called on the delegate (if implemented) when the request completes successfully.
id <ChannelDelegate> delegate;
SEL didRecieveImageForChannelSelector;
}
@property (strong, nonatomic) id delegate;
@property (assign) SEL didRecieveImageForChannelSelector;
- (void)getChannelImageForChannelId:(int)channelId externalRefference:(NSString*)url indexPath:(NSIndexPath*)indexPath;
- (id)delegate;
@end
Channel.m
:
#import "Channel.h"
#import <objc/runtime.h>
@implementation Channel
static char kAssociationKey;
@synthesize didRecieveImageForChannelSelector;
@synthesize delegate;
- (void)getChannelImageForChannelId:(int)channelId externalRefference:(NSString*)url indexPath:(NSIndexPath*)indexPath
{
[self setDidRecieveImageForChannelSelector:@selector(didRecieveImageForChannel:indexPath:)];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *imagePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d.gif", channelId]];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imagePath];
if (fileExists)
{
NSLog(@"Downloaded image!");
[[self delegate] performSelector:[self didRecieveImageForChannelSelector] withObject:imagePath withObject:indexPath];
}
else {
NSLog(@"Need to fetch it.!");
NSURL *theUrl = [NSURL URLWithString:url];
ASINetworkQueue *newQueue = [[ASINetworkQueue alloc] init];
[newQueue setRequestDidFinishSelector:@selector(channelImageFetched:)];
[newQueue setRequestDidFailSelector:@selector(processFailed:)];
[newQueue setDelegate:self];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:theUrl];
[request setTimeOutSeconds:60];
[request setDownloadDestinationPath:imagePath];
[newQueue addOperation:request];
objc_setAssociatedObject(request, &kAssociationKey, indexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[newQueue go];
}
}
- (id)delegate
{
id d = delegate;
return d;
}
- (void)setDelegate:(id)newDelegate
{
delegate = newDelegate;
}
// Handle process two
- (void)channelImageFetched:(ASIHTTPRequest *)request
{
NSLog(@"channelImageFetched!");
NSIndexPath *indexPath = objc_getAssociatedObject(request, &kAssociationKey);
NSString *imagePath = request.downloadDestinationPath;
[[self delegate] performSelector:[self didRecieveImageForChannelSelector] withObject:imagePath withObject:indexPath];
NSLog(@"File downloaded!");
}
- (void) processFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
UIAlertView *errorView;
errorView = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(@"Whoops!", @"Errors")
// message: NSLocalizedString(@"An error occured while preforming the request. Please try again.", @"Network error")
message: [error localizedDescription]
delegate: self
cancelButtonTitle: NSLocalizedString(@"Close", @"Errors") otherButtonTitles: nil];
[errorView show];
/* NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[request error], @"Error",
[request url], @"URL",
[[NSDate alloc] init], @"timestamp", nil];
[FlurryAPI logEvent:@"APNS-Could not fetch data." withParameters:dictionary timed:YES];
*/
}
@end
Ошибка, которую я получаю, время от времени, кажется, различается, однако я вижу ошибки, которые я получил:
2011-09-26 13: 11: 57.605 TVSports [4541: ef03] Готово!2011-09-26 13: 11: 57.609 TVSports [4541: ef03] Скачанное изображение!2011-09-26 13: 11: 57.610 TVSports [4541: ef03] Получил это!2011-09-26 13: 11: 57.613 TVSports [4541: ef03] Нужно достать, если!2011-09-26 13: 11: 57.616 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.618 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.621 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.624 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.629 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.633 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.663 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.669 TVSports [4541: ef03] Нужно достать его!2011-09-26 13: 11: 57.846 TVSports [4541: ef03] - [UIDeviceWhiteColor channelImageFetched:]: нераспознанный селектор отправлен на экземпляр 0x65a1e302011-09-26 13: 11: 57.847 TVSports [4541: ef03] * Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: '- [UIDeviceWhiteColor channelImageFetched:]: нераспознанный селектор отправлен в экземпляр 0x65a1e30'* Первый вызов стека вызовов:(0x15da272 0x1769ce6 0x15dbf0d 0x1540e2f 0x1540c12 0x15dc092 0x3adf8 0x15dc092 0x24c43 0x15dc092 0xef9fac 0x15aec0f 0x15118c3 0x15111a4 0x1510b04 0x1510a1b 0x1ce6f67 0x1ce702c 0x608cf2 0x2718 0x2675 0x1)прекратить вызывать выбрасывание исключения (gdb)
Или я получаю EXC_BAD_ACCESS для строки в ASIHTTPRequest (которую я не могу воспроизвести за последние 10 попыток.)
Может кто-нибудь показывать, чтоЯ делаю не так?Где весь мой код испорчен?