2011-07-25 44 views
36

Tôi đang phát triển một plugin cho ứng dụng iOS. Tôi đang biên dịch nó thành một tập tin .a mà sau đó được sử dụng bởi dự án xcode chính.liên kết các danh mục mục tiêu-c trong thư viện tĩnh

Cho đến nay tôi đã tạo danh mục của lớp UIDevice trong thư viện này. Khi tôi chạy dự án chính sử dụng thư viện này nó bị treo do một selector không được công nhận

- [UIDevice nền tảng]: chọn không được công nhận gửi đến dụ

nền tảng là một trong những fuinctions tôi thêm vào thông qua các thể loại.

Vì vậy, tôi nghĩ rằng nó không liên kết các chức năng đó và thêm hàm c vào cùng một tệp với danh mục UIDevice sau đó gọi nó từ mã của tôi.

Lần này dự án chính chạy tốt ... Vì vậy, tôi nghĩ có lẽ đó là một cái gì đó khác tôi đã làm và loại bỏ các chức năng C. Nhưng lo và nhìn thấy nó bị rơi lại do bộ chọn không được công nhận ..

Câu hỏi của tôi: Tại sao xcode bỏ qua định nghĩa danh mục trừ khi tôi gọi hàm được khai báo trong cùng một tệp?

Có cài đặt xcode tôi có thể thay đổi để làm cho nó bao gồm các phương pháp này từ danh mục UIDevice bất kể tôi có gọi hàm từ tệp đó hay không?

cổ vũ

+0

có thể trùng lặp của [loại Mục tiêu-C trong thư viện tĩnh] (http://stackoverflow.com/questions/2567498/objective-c-categories-in-static-library) – TalkLittle

Trả lời

71

Check-out Building Objective-C static libraries with categories:

Objective-C không định nghĩa những biểu tượng liên kết cho mỗi chức năng (hoặc phương pháp, trong Objective-C) - thay vào đó, những biểu tượng mối liên kết này chỉ được tạo cho mỗi lớp. Nếu bạn mở rộng một lớp đã tồn tại từ trước với các danh mục, thì trình liên kết không biết liên kết mã đối tượng của việc triển khai lớp lõi và triển khai danh mục. Điều này ngăn chặn các đối tượng được tạo trong ứng dụng kết quả là trả về một bộ chọn được xác định trong danh mục.

Để giải quyết vấn đề này, mục tiêu liên kết với thư viện tĩnh phải chuyển tùy chọn -ObjC cho trình liên kết. Cờ này làm cho trình liên kết tải mọi tệp đối tượng trong thư viện xác định lớp hoặc danh mục Mục tiêu-C . Mặc dù tùy chọn này thường sẽ dẫn đến tệp thực thi lớn hơn (do mã đối tượng bổ sung được tải vào ứng dụng ), nó sẽ cho phép tạo thành công các thư viện tĩnh Mục tiêu-C hiệu quả chứa các danh mục trên các lớp hiện có.


quan trọng: Đối với các ứng dụng 64-bit và iPhone OS, có một lỗi mối liên kết có thể ngăn chặn -ObjC từ tải các đối tượng tập tin từ tĩnh thư viện mà chỉ chứa loại và không có các lớp học. Cách giải quyết là sử dụng cờ -all_load hoặc -force_load.

Nguồn: @albertamg (linking objective-c categories in a static library)

+0

Cảm ơn bạn đã phản hồi nhanh! Tôi đã thêm cờ liên kết cho cả hai dự án nhưng vẫn gặp lỗi tương tự. Tuy nhiên các tập tin của các ứng dụng đã lớn hơn nó nên được như vậy có lẽ gọi một chức năng giả là giải pháp tốt nhất trong trường hợp này. – micken

+2

@micken Quan trọng: Đối với các ứng dụng 64-bit và iPhone OS, có một lỗi liên kết ngăn -ObjC tải các tệp đối tượng từ các thư viện tĩnh chỉ chứa các loại và không có lớp. Cách giải quyết là sử dụng cờ -all_load hoặc -force_load. – albertamg

+0

Lỗi này vẫn tồn tại cho đến nay? –

8

Tôi đã có cùng một vấn đề. Một phương thức được định nghĩa trong một danh mục được xác định trong một dự án con dẫn đến một ngoại lệ bộ chọn không được công nhận. (Trong thực tế, điều này được biểu hiện là không có khả năng xác định một lớp con UILabel trong Interface Builder; XIB chứa lớp được hiển thị trong IB (UILabel hoặc UIView, tùy thuộc vào những gì tôi kéo ở đó), thay vì lớp mà tôi đã nhập vào, trông như một lỗi XCode lạ)

các giải pháp mà làm việc cho tôi đã được sử dụng -force_load:.

Trong bảng điều khiển bên trái, chọn dự án chính của bạn (mục root). Ở bên phải, bạn sẽ thấy PROJECTTARGETS. Chọn TARGETS. Đi tới "Cài đặt Xây dựng" (ở phía trên) - "Liên kết" - "Cờ liên kết khác" và giả sử tiểu dự án của bạn được gọi là XXXXX, thêm -force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a tại đó (mục có hai phần phụ, Gỡ lỗi và Phát hành, nhưng bạn bấm vào mục ghép này để nếu ảnh hưởng đến cả Debug và Release).

Lưu ý rằng -force_load hoạt động cho một thư viện duy nhất và bạn có thể cần chỉ định một tệp tin -force_load riêng biệt cho mỗi thư viện tiểu dự án.

+1

Tôi gặp lỗi "libtool: ký tự tùy chọn không xác định' f 'trong: -force_load "Bất kỳ ý tưởng nào? – docchang

+0

Đây là câu trả lời hay, cảm ơn! – RaffAl

-1

Tôi gặp sự cố này và đã dành gần 1 giờ để giải quyết vấn đề. Cảm ơn Chúa! Nó đã được thực hiện. Các phương thức được định nghĩa phải là kiểu tĩnh!

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