2013-02-06 41 views
14

Tôi đã nhận thấy rằng các danh mục AFNetworking và SDWebImage trên UIImageView có cùng tên phương thức.Hai Danh mục trên cùng một Lớp có cùng tên phương thức

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 
{ 
... 
} 

và 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]; 
} 

... 

Trong Xcode khi ta truyền cho chuột lên phương pháp SDWebImage nó chuyển hướng tôi đến phương pháp AFNetworking và ngược lại.

Tôi có thể mong đợi hành vi nào? Tôi có nên chỉ bao gồm tiêu đề cho danh mục phù hợp trong lớp tôi muốn sử dụng không? Điều gì sẽ xảy ra nếu cùng một lớp cần sử dụng cả hai triển khai của danh mục?

Một câu hỏi liên quan khác "What happens if two ObjC categories override the same method?" không hoàn toàn giống như vậy bởi vì cả AFNetworking và SDWebImage đều đang thêm Danh mục vào cùng một lớp chứ không phải lớp con. Trong trường hợp này chỉ một khi lớp đang được sử dụng và 2 loại có vẻ xung đột.

+1

Liên quan: ["Điều gì sẽ xảy ra nếu nhiều danh mục thực hiện cùng một phương pháp?"] (Http://stackoverflow.com/a/1085500/335858). – dasblinkenlight

+0

Đây là Xấu, và đó chính xác là lý do tại sao các khung bên thứ ba được khuyến khích mạnh mẽ để sử dụng các tiền tố trên các phương thức mà chúng thêm vào các lớp khung khác thông qua các danh mục. Các tệp tiêu đề không ảnh hưởng đến điều này; thời gian chạy tải các loại bất kể, và thứ tự, và do đó việc thực hiện bạn kết thúc với, là không xác định. –

+0

*** Không phải là sự lừa đảo của [Điều gì sẽ xảy ra nếu hai loại ObjC ghi đè lên cùng một phương pháp?] (Http://stackoverflow.com/q/3221972) Có lẽ là một sự lừa đảo của [Mở rộng một lớp bằng cách sử dụng các loại với các phương thức giống hệt nhau name] (http://stackoverflow.com/q/4764977), [Các phương pháp ghi đè bằng cách sử dụng các danh mục trong ObjC] (http://stackoverflow.com/q/5272451) và [Ghi đè một phương thức trong ObjC qua danh mục] (http : //stackoverflow.com/q/14259517) –

Trả lời

7

Va chạm tên thực sự là điều có thể xảy ra trong thời gian chạy Objective-C ... Apple advises the use of 'prefix' on methods names.

Hành vi dự kiến: chỉ loại/phương thức cuối cùng được tải bởi thời gian chạy mới có hiệu lực. Đó là cái nào? Câu hỏi không phù hợp!

Lời khuyên của tôi: đổi tên!

+1

Tiêu đề không ảnh hưởng đến hành vi này; nếu các tệp triển khai đang được biên dịch, sự va chạm sẽ xảy ra, và thứ tự tải tại thời gian chạy là không xác định (mặc dù có khả năng lặp lại). –

+0

Rất tiếc, thực sự ... – Vinzzz

+0

Vì vậy, một câu trả lời cho một số dự án sẽ là chia rẽ các dự án này trên Github và đổi tên các tên phương thức thành không xung đột, có thể gói chúng trong một cocoapod và tiếp tục với mã của chúng? Rất may là không khó! – PaulWoodIII

8

Rename dường như không phải là cách tốt nhất để giải quyết vấn đề,

chỉ cần sử dụng:

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

}]; 

từ SDWebImage mà không tồn tại trong AFNetworking

+0

Có điều đó đúng và sẽ hoạt động cho ví dụ nhưng ở cấp cao hơn, cách xa ví dụ AFNetworking/SDWEbImageCache, "Điều gì xảy ra nếu cùng một lớp cần sử dụng cả hai triển khai của danh mục? " Tôi nghĩ nếu đây là trường hợp bạn nên đổi tên danh mục. – PaulWoodIII

2

Đối với bất cứ ai tìm cách để sử dụng cả SDWebImage và AFNetworking như hiện tại, đây là giải pháp thượng cổ của tôi để ngăn cản việc sử dụng các phương pháp va chạm:

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

Rõ ràng đây không phải là bằng chứng trong tương lai và dễ bị phá vỡ nếu việc triển khai các phương pháp này thay đổi trong AFNetworking hoặc SDWebImage. Nó là một giải pháp lý tưởng. Nói cách khác, có nguy cơ của riêng bạn!

+0

Khi tôi hiểu ý chính, ý tưởng là không dùng phương pháp được đề cập. Tôi không nhận được bất kỳ cảnh báo, tuy nhiên. Điều đó cũng không phụ thuộc vào, loại nào được sử dụng? – Grav

+1

Tôi đã thêm một cách dừng xây dựng, nếu phương pháp va chạm được sử dụng. Tôi đã nhận xét ý chính. – Grav

Các vấn đề liên quan