Không hề ... là câu trả lời cho câu hỏi ban đầu:
Làm cách nào để tìm kiếm đường dẫn đến hình ảnh bằng cách sử dụng phương thức NSBundle pathForResource khi tạo UIImage bằng imageNamed?
Không có nhiều .. là cách đúng câu trả lời chấp nhận từ Zoul và một trong những khác từ Ranga đang có. Để công bằng: chúng là chính xác nếu bạn đang nói về cấu trúc thư mục gói ứng dụng hoặc cho trường hợp (hiếm) trong đó hình ảnh nằm trong thư mục "xanh dương" trong Xcode (nhiều hơn về sau), nhưng không phải cho nhiều nhất các trường hợp phổ biến
Dù sao, vào một câu trả lời đúng.
Như thường lệ, tôi đã tìm thấy câu hỏi này trong khi tự mình tìm câu trả lời. Tôi chưa bao giờ tìm thấy tài liệu hoặc các câu trả lời khác cho câu hỏi này đạt yêu cầu, vì vậy tôi quyết định thử nghiệm.
Chi tiết kiểm tra của tôi là tất cả bên dưới, nhưng hãy để tôi tóm tắt kết quả tại đây. Nói tóm lại, khi sử dụng imageNamed: để tải hình ảnh của bạn, nó phụ thuộc vào nơi bạn đặt chúng:
nếu hình ảnh của bạn trong thư mục gốc của dự án của bạn, ngay cả khi tổ chức trong một nhóm Xcode hoàn toàn hợp lý, sau đó không , bạn không cần cần phải suy nghĩ về đường dẫn: chỉ cần tên hình ảnh.
nếu ảnh của bạn nằm trong nhóm được đính kèm vào thư mục trong hệ thống tệp của bạn, thông qua "tạo nhóm cho thư mục được thêm" thì bạn vẫn không cần phải lo lắng về tên.
nếu hình ảnh của bạn nằm trong nhóm "xanh", được đính kèm vào thư mục trong hệ thống tệp của bạn qua "tạo thư mục tham chiếu cho thư mục được thêm", sau đó bạn có thể tải nó bằng imageNamed: được đề xuất (trùng hợp?) bởi câu trả lời được chấp nhận ở trên.
nếu bạn sử dụng thay thế chính cho imageNamed :, imageWithContentsOfFile :, bạn thực sự cần đường dẫn đầy đủ đến tệp bao gồm đường dẫn gói, có nghĩa là bạn cần biết cấu trúc điều hướng Xcode chuyển thành đường dẫn trong gói của bạn như thế nào Cấu trúc thư mục.
Sự khác biệt quan trọng khác giữa hai phương pháp:
- imageNamed không yêu cầu bạn chỉ định phần mở rộng filetype, nên chỉ đơn thuần là "biểu tượng" không phải là "icon.png", trong khi imageWithContentsOfFile làm yêu cầu tên tệp đầy đủ
- điểm đầu tiên này sẽ giúp với tính năng thứ hai: imageNamed sẽ tự động tải phiên bản võng mạc của hình ảnh nếu có, bằng cách thêm @ 2 x vào tên tệp của bạn. Vì vậy, nếu bạn yêu cầu "biểu tượng", trên màn hình hiển thị võng mạc , nó sẽ cố tải "[email protected]". imageWithContentsOfFile không
- imageNamed lưu trữ hình ảnh: và trong đó có rất nhiều tranh cãi xung quanh nó: Nếu bạn tìm kiếm SO hoặc web lớn bạn sẽ tìm thấy nhiều bài viết đề xuất bạn tránh nó vì nó không ' t xóa bộ nhớ cache đúng cách. Điều này, tuy nhiên, đã được cố định năm trước, vì vậy bạn không cần phải lo lắng về nó không xóa bộ nhớ cache của nó. Bạn làm vẫn còn cần phải lo lắng về thực tế là nó lưu trữ ở tất cả, mặc dù. Nếu hình ảnh của bạn là lớn và không được tải rất thường xuyên, bạn sẽ bảo tồn bộ nhớ bằng cách tải chúng từ tệp và không lưu vào bộ nhớ cache. Đây là không có gì để làm với rò rỉ: ngay cả khi bạn không bị rò rỉ, bạn vẫn còn có bộ nhớ giới hạn trên thiết bị và bạn không muốn cache không cần thiết. Đó là sự cân bằng bộ nhớ đệm cổ điển: điều gì là quan trọng hơn trong trường hợp của bạn là ? Hiệu suất bộ nhớ hoặc hiệu suất CPU (thời gian).
Vì vậy, với các thử nghiệm của tôi.
Điều tôi đã làm là tạo một ứng dụng UITableView đơn giản với 3 tệp biểu tượng đơn giản, được hiển thị trong các hàng của bảng bằng các phương pháp khác nhau. Các biểu tượng khác nhau ở vị trí của chúng trong cấu trúc dự án Xcode. Lưu ý sự nhấn mạnh trên Xcode. Chìa khóa để hiểu câu trả lời cho câu hỏi ban đầu là có ba cấu trúc thư mục dự án hoàn toàn khác nhau trong ứng dụng iOS: Có một cấu trúc bạn thấy trong trình điều hướng Xcode, một trong hệ thống tệp cho cùng một dự án mà bạn thấy trong Trình tìm kiếm (nhấp chuột phải vào bất kỳ mục nào trong trình điều hướng Xcode và chọn "hiển thị trong Trình tìm kiếm") và, bạn hiếm khi thấy, cấu trúc thư mục "bó" của ứng dụng được triển khai. Bạn có thể thấy cái cuối cùng này trong Finder - bằng cách tìm ứng dụng của bạn trong ~/Library/Application Support/iPhone Simulator, và đi sâu vào thư mục .app. Tôi sẽ cho bạn xem một bức ảnh của tôi trong một phút.
Vì vậy, trong ứng dụng của tôi, tôi kéo cả ba biểu tượng png tập tin hình ảnh vào Xcode theo những cách khác nhau:
icon1.png (đồng hồ), tôi lôi vào cuộc như một tập tin vào thư mục gốc của Xcode dự án, thì I sau này đã tạo một nhóm mới trong Xcode và kéo nó vào . Nhóm này không được đại diện bởi bất kỳ thư mục nào trong tệp hệ thống: đó là một nhóm Xcode thuần túy. Do đó tên của nó: "JustGroup"
icon2.png (một mắt), tôi ban đầu đặt hệ thống tập tin của tôi trong thư mục gọi là "RealDir", và tôi kéo toàn bộ thư mục này vào Xcode, và khi hỏi, tôi đã chọn tùy chọn "Tạo nhóm cho bất kỳ thư mục được thêm nào". Điều này có nghĩa là nhóm RealDir trong Xcode được đính kèm vào thư mục thực được gọi là RealDir trong hệ thống tệp (trong thư mục dự án của tôi) và biểu tượng đó2.png nằm trong đó.
icon3.png (mục tiêu), tôi cũng có trong một thư mục riêng biệt, mà tôi cũng đã kéo vào Xcode. Chỉ có thời gian này tôi đã chọn tùy chọn radio thứ hai "Tạo tài liệu tham khảo thư mục cho bất kỳ thư mục nào được thêm". Điều này tạo ra một nhóm gọi là "xanh" trong Xcode. Thông tin thêm về điều này là về sau. Tôi gọi nhóm này (và thư mục) "FolderReference"
Dưới đây là một shot của sự lựa chọn đó Xcode mang đến cho bạn: 
Và đây là những gì cấu trúc dự án của tôi trông như thế nào trong Xcode: 
Bây giờ, trong ứng dụng của tôi, tôi đã sử dụng hai phương pháp để tải từng biểu tượng: UIImage imageNamed: và UIImage imageWithContentsOfFile. Tôi tạo ra một loạt các hàng trong bảng của tôi với tiêu đề của mỗi ô là tên của nhóm chứa biểu tượng: JustGroup, RealDir hoặc FolderReference, cộng với tên của phương thức được sử dụng: imageNamed vs fromFile (mà tôi sử dụng như viết tắt của imageWithContentsOfFile)
Nhãn chi tiết của ô (văn bản mờ hơn bên dưới tiêu đề) hiển thị tên tệp hoặc tên đường dẫn mà tôi đã cung cấp cho phương thức.
Để rõ ràng, trong trường hợp "fromFile", tôi đang thêm đường dẫn gói vào tên "tương đối" mà bạn nhìn thấy. Vì vậy cho "fromFile", tôi thực sự sử dụng mã này:
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *imagePath = [NSString stringWithFormat:@"%@/%@", bundlePath, filePath];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
nơi "filepath" là con đường mà bạn nhìn thấy trong nhãn bảng chi tiết tế bào. Đối với imageNamed :, mặt khác, tệp tệpPath trong chi tiết ô được thông qua nguyên văn.
Và hàng image là, một cách tự nhiên, hình ảnh được tải. Vì vậy, đối với các hàng trong bảng không có hình ảnh, tải hình ảnh không thành công.
Ở đây, tóm lại, là kết quả. Nếu bạn không đọc gì về bài đăng này, ít nhất là lướt qua hình ảnh này sẽ cho bạn biết tất cả những gì bạn cần biết.

Dưới đây là lời giải thích cơ bản tại các điểm dễ dàng tiêu hóa:
vì nó khẳng định trong các tài liệu chính thức, imageNamed: Phương pháp tải hình ảnh từ các gói ứng dụng. Điều này có nghĩa là bạn không cần chỉ định vị trí gói, chỉ tên tệp. Và thậm chí sau đó, chỉ là tên cơ sở của tệp. Tài liệu này hơi mỏng ở đây, nó thực sự sẽ làm cho nó rõ ràng rằng nó tải hình ảnh từ đường dẫn tệp nhất định tương đối vào thư mục gốc của gói ứng dụng.
(đây là kicker, chú ý đến điều này) quy tắc đó về thư mục bó, tham chiếu đến thư mục gốc trong gói ứng dụng được triển khai của bạn. Nếu bạn đi khám phá, điều đó có nghĩa là trong thư mục ".app". Đó là không giống nhau như thư mục gốc của dự án Xcode trong navigator Xcode, cũng không phải là giống như các thư mục gốc của dự án Xcode trong công cụ tìm
này là bởi vì, khi triển khai ứng dụng của bạn để thiết bị (hoặc trình mô phỏng) tất cả các thư mục dự án được đại diện bởi "nhóm cho thư mục được thêm" là được làm phẳng. Đó là, thư mục bị bỏ qua, và tất cả các nội dung của nó được bỏ qua một cách vô thức trong thư mục gốc của gói. (Tôi nói "unceremoniously" bởi vì nếu có các tập tin có cùng tên trong các thư mục khác nhau, họ sẽ va chạm ở đây và bạn sẽ không nhận được sự trợ giúp trong việc giải quyết các vấn đề gây ra.) Đây là trường hợp của RealDir trong ví dụ của tôi: trong ứng dụng được triển khai, RealDir không còn tồn tại nữa và biểu tượng2.png còn lại để kết hợp với dân số chung (đáng sợ). Nó gần như không nói rằng "JustGroup", nhóm Xcode thuần túy hợp lý, cũng bị bỏ qua - nó chưa bao giờ là thư mục thực, chỉ là một trợ giúp trực quan cho người dùng Xcode - và icon1.png cũng nằm trong thư mục gốc.
"thư mục màu xanh", mặt khác, có nghĩa là, các thư mục đại diện bởi "tài liệu tham khảo thư mục cho các thư mục bổ sung", là trên thực tế vẫn giữ trong gói ứng dụng cấu trúc thư mục. Điều này, rõ ràng là điểm của các thư mục màu xanh: chúng cung cấp cho bạn một cách để tạo cấu trúc thư mục trong ứng dụng được triển khai của bạn. Tôi không chắc chắn về bản gốc này, nhưng một trường hợp sử dụng tốt là nơi bạn có một số thư mục chứa các phiên bản thay thế của các tệp tài nguyên có cùng tên và bạn muốn ứng dụng của mình có thể chuyển đổi giữa chúng khi chạy bằng cách thay đổi thư mục. Dù sao, icon3.png trong FolderReference của tôi, vẫn nằm trong thư mục FolderReference của tôi trong ứng dụng được triển khai.
- Đây là lý do tại sao imageNamed: không thể tìm thấy nó với "Icon3", nhưng thể thấy nó với "FolderReference/Icon3"
- imageWithContentsOfFile đã có thể tìm thấy nó cũng sử dụng FolderReference, nhưng chỉ khi được đính kèm, hãy nhớ đến đường dẫn gói đầy đủ bằng cách sử dụng mã ở trên. (Sự khác biệt chính ở đây: imageNamed làm việc với một đường dẫn tương đối trong trường hợp này, imageWithContentsOfFile luôn làm việc với một đường dẫn tuyệt đối).
Để làm rõ, đây là một cấu trúc thư mục của tôi:
Bạn thấy Xcode cấu trúc hoa tiêu dự án của tôi ở trên, đây là thư mục hệ thống tập tin bên dưới: 
Và cuối cùng, có lẽ quan trọng nhất, cấu trúc thư mục hệ thống tệp bó được triển khai: 
Lưu ý: Tôi tìm thấy t tại vị trí này trên máy Mac của tôi: bạn sẽ tìm thấy vị trí của bạn ở một vị trí tương tự - bạn có thể phải tìm kiếm một chút để tìm thư mục con có tên xấu xí-GUID nào chứa ứng dụng của bạn.
~/Library/Application Support/iPhone Simulator/5.1/Applications/4EB386B2-CD7E-4590-9757-18DDDEE6AF4F/ImageLoadingTest.app
Tôi hy vọng điều này sẽ hữu ích. Thử nghiệm, khám phá và cuối cùng, mô tả nó chắc chắn đã giúp tôi.
[Ở đây] (http://stackoverflow.com/questions/924740/dispelling-the-uiimage-imagenamed-fud) là bài đăng SO về cách sử dụng imageNamed trong mã của bạn mà bạn có thể muốn đọc. Không liên quan trực tiếp đến câu hỏi của bạn, nhưng tôi thấy nó rất hữu ích. – zero0cool