2013-02-06 194 views
14

我注意到UIImageView上的AFNetworking和SDWebImage類別具有相同的方法名稱。使用相同的方法名稱在同一類上的兩個類別

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中,當我命令點擊它重定向我到AFNetworking方法和反之亦然SDWebImage方法。

我可以期待哪種行爲?我是否應該只在課堂中包含適當類別的標題,我想在其中使用它?如果同一個類需要同時使用這兩個類的實現呢?

另一個相關的問題「What happens if two ObjC categories override the same method?」與此不太一樣,因爲AFNetworking和SDWebImage都將類別添加到相同的類而不是子類。在這種情況下,只有一次課程正在使用,兩個類別似乎有衝突。

+1

相關:[「如果多個類別實現相同的方法呢?」](http://stackoverflow.com/a/1085500/335858)。 – dasblinkenlight

+0

這很糟糕,這也正是爲什麼強烈建議第三方框架在通過類別將其添加到其他框架類的方法上使用前綴的原因。頭文件對此沒有影響;運行時會加載類別,而且順序以及最終的實現都是未定義的。 –

+0

***不是*** [如果兩個ObjC類別重寫相同的方法會發生什麼?](http://stackoverflow.com/q/3221972)可能是[使用相同的方法使用類別擴展類名稱](http://stackoverflow.com/q/4764977),[在ObjC中使用類別重寫方法](http://stackoverflow.com/q/5272451)和[在類別中覆蓋ObjC中的方法](http ://stackoverflow.com/q/14259517) –

回答

7

名稱碰撞確實是在Objective-C運行時可能發生的事情... Apple advises the use of 'prefix' on methods names

預期行爲:只有運行時加載的最後一個類/方法纔有效。 這是哪一個? 糟糕的問題!

我的建議:重命名!

+1

標題對此行爲沒有影響;如果正在編譯實現文件,則會發生衝突,並且運行時加載的順序不確定(儘管可能會重複)。 –

+0

哎呀,的確... – Vinzzz

+0

因此,對於一些項目的答案將是在Github上分發這些項目,並將方法名稱重命名爲不衝突,也許將它們打包在一個cocoapod中並繼續使用它們的代碼?謝天謝地,這不是很難! – PaulWoodIII

8

重命名似乎並沒有成爲解決這個問題的最好辦法,

只需使用:

[cell.imageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"placeholder"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) { 

}]; 

SDWebImage這不AFNetworking

+0

是的,這是真的,並且可以用於示例,但是在更高級別上,遠離AFNetworking/SDWEbImageCache示例,「如果同一類需要使用這兩個類別的實現?「我認爲如果是這種情況,你應該重新命名這個類別。 – PaulWoodIII

2

存在任何希望同時使用SDWebImage和AFNetworking,這裏是我的穴居人解決方案,以阻止使用碰撞方法:

https://gist.github.com/sibljon/5957892

這顯然不是未來的證明,並且如果這些方法的實現在AFNetworking或SDWebImage中發生更改,則很容易中斷。這遠非理想的解決方案。換句話說,風險自擔!

+0

正如我理解的要點,這個想法是不贊成有問題的方法。但是,我沒有收到任何警告。這不也取決於哪個類別被使用? – Grav

+1

如果使用碰撞方法,我添加了停止構建的方法。我評論了這個要點。 – Grav

相關問題