Две категории одного и того же класса с тем же именем метода
Я заметил, что категории AFNetworking и SDWebImage в UIImageView имеют одно и то же имя метода.
AFNetworking:
- (void)setImageWithURL:(NSURL *)url {
[self setImageWithURL:url placeholderImage:nil];
}
- (void)setImageWithURL:(NSURL *)url
placeholderImage:(UIImage *)placeholderImage
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPShouldHandleCookies:NO];
[request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
[self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil];
}
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(UIImage *)placeholderImage
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure
{
...
}
и SDWebImage
- (void)setImageWithURL:(NSURL *)url
{
[self setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
{
[self setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options
{
[self setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
}
...
В Xcode, когда я командую метод SDWebImage, он перенаправляет меня на метод AFNetworking и наоборот.
Какое поведение я могу ожидать где? Должен ли я включать заголовок для соответствующей категории в класс, в который я хотел бы использовать его? Что делать, если один и тот же класс должен использовать обе реализации категории?
Другой связанный с этим вопрос "Что произойдет, если две категории ObjC переопределяют один и тот же метод?" не совсем то же самое, что и потому, что как AFNetworking, так и SDWebImage добавляют Категории на тот же класс, а не подкласс. В этом случае используется только один класс, и 2 категории, похоже, находятся в конфликте.
Ответы
Ответ 1
Имя столкновения - это действительно то, что может произойти в Objective-C времени выполнения...
Apple советует использовать префикс для имен методов.
Ожидаемое поведение: эффективна только последняя категория/метод, загруженный средой выполнения.
Который из них?
Плохой вопрос!
Мой совет: переименуйте!
Ответ 2
Переименование не похоже на лучший способ решить проблему,
просто используйте:
[cell.imageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"placeholder"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
}];
из SDWebImage
, который не существует в AFNetworking
Ответ 3
Для тех, кто хочет использовать как SDWebImage, так и AFNetworking as-is, вот мое решение пещерного человека, чтобы препятствовать использованию сталкивающихся методов:
https://gist.github.com/sibljon/5957892
Это, очевидно, не будущее доказательство, и склонно ломаться, если реализация этих методов изменяется в AFNetworking или SDWebImage. Это далеко не идеальное решение. Другими словами, на свой страх и риск!