Kategori Objective-C di perpustakaan statis

153

Dapatkah Anda membimbing saya cara menautkan pustaka statis ke proyek iPhone dengan benar. Saya menggunakan proyek perpustakaan statis ditambahkan ke proyek aplikasi sebagai ketergantungan langsung (target -> umum -> ketergantungan langsung) dan semua berfungsi OK, tetapi kategori. Kategori yang ditentukan di perpustakaan statis tidak berfungsi di aplikasi.

Jadi pertanyaan saya adalah bagaimana cara menambahkan perpustakaan statis dengan beberapa kategori ke proyek lain?

Dan secara umum, apa praktik terbaik untuk digunakan dalam kode proyek aplikasi dari proyek lain?

Vladimir
sumber
1
baik, menemukan beberapa jawaban dan sepertinya pertanyaan ini sudah dijawab di sini (maaf melewatkannya stackoverflow.com/questions/932856/… )
Vladimir

Jawaban:

228

Solusi: Pada Xcode 4.2, Anda hanya perlu pergi ke aplikasi yang menautkan ke perpustakaan (bukan perpustakaan itu sendiri) dan klik proyek di Project Navigator, klik target aplikasi Anda, lalu buat pengaturan aplikasi, lalu cari "Lainnya Tautan Bendera ", klik tombol +, dan tambahkan '-ObjC'. '-all_load' dan '-force_load' tidak lagi diperlukan.

Detail: Saya menemukan beberapa jawaban di berbagai forum, blog, dan dokumen Apple. Sekarang saya mencoba membuat ringkasan pendek dari pencarian dan eksperimen saya.

Masalah disebabkan oleh (kutipan dari apel. T&J Teknis QA1490 https://developer.apple.com/library/content/qa/qa1490/_index.html ):

Objective-C tidak mendefinisikan simbol linker untuk setiap fungsi (atau metode, di Objective-C) - sebagai gantinya, simbol linker hanya dihasilkan untuk setiap kelas. Jika Anda memperluas kelas yang sudah ada sebelumnya dengan kategori, linker tidak tahu untuk mengaitkan kode objek dari implementasi kelas inti dan implementasi kategori. Ini mencegah objek yang dibuat dalam aplikasi yang dihasilkan dari menanggapi pemilih yang didefinisikan dalam kategori.

Dan solusi mereka:

Untuk mengatasi masalah ini, pustaka statis harus meneruskan opsi -ObjC ke tautan. Bendera ini menyebabkan tautan untuk memuat setiap file objek di pustaka yang mendefinisikan kelas atau kategori Objective-C. Sementara opsi ini biasanya akan menghasilkan executable yang lebih besar (karena kode objek tambahan dimuat ke dalam aplikasi), itu akan memungkinkan keberhasilan penciptaan perpustakaan statis Objective-C efektif yang berisi kategori pada kelas yang ada.

dan ada juga rekomendasi di FAQ Pengembangan iPhone:

Bagaimana cara menautkan semua kelas Objective-C di perpustakaan statis? Atur pengaturan build Other Linker Flags ke -ObjC.

dan deskripsi bendera:

- all_load Memuat semua anggota perpustakaan arsip statis.

- ObjC Memuat semua anggota perpustakaan arsip statis yang menerapkan kelas atau kategori Objective-C.

- force_load (path_to_archive) Memuat semua anggota perpustakaan arsip statis yang ditentukan. Catatan: -all_load memaksa semua anggota dari semua arsip dimuat. Opsi ini memungkinkan Anda untuk menargetkan arsip tertentu.

* kita dapat menggunakan force_load untuk mengurangi ukuran biner aplikasi dan untuk menghindari konflik yang dapat menyebabkan all_load dalam beberapa kasus.

Ya, ini berfungsi dengan * .a file yang ditambahkan ke proyek. Namun saya punya masalah dengan proyek Lib ditambahkan sebagai ketergantungan langsung. Tetapi kemudian saya menemukan bahwa itu adalah kesalahan saya - proyek ketergantungan langsung mungkin tidak ditambahkan dengan benar. Ketika saya menghapusnya dan menambahkan lagi dengan langkah-langkah:

  1. Seret & jatuhkan file proyek lib di proyek aplikasi (atau tambahkan dengan Project-> Add to project ...).
  2. Klik panah pada ikon lib project - nama file mylib.a ditampilkan, seret file mylib.a ini dan letakkan di Target -> Tautkan Biner Dengan Grup Perpustakaan.
  3. Buka info target di halaman pertama (Umum) dan tambahkan lib saya ke daftar dependensi

setelah itu semua berfungsi OK. Bendera "-ObjC" sudah cukup dalam kasus saya.

Saya juga tertarik dengan ide dari http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html blog. Penulis mengatakan ia dapat menggunakan kategori dari lib tanpa mengatur -all_load atau -ObjC flag. Dia hanya menambah kategori file h / m kosong antarmuka kelas dummy / implementasi untuk memaksa linker menggunakan file ini. Dan ya, trik ini berhasil.

Tetapi penulis juga mengatakan ia bahkan tidak membuat objek boneka. Mm ... Seperti yang saya temukan, kita harus secara eksplisit memanggil beberapa kode "nyata" dari file kategori. Jadi setidaknya fungsi kelas harus dipanggil. Dan kita bahkan tidak perlu kelas dummy. Fungsi c tunggal melakukan hal yang sama.

Jadi jika kita menulis file lib sebagai:

// mylib.h
void useMyLib();

@interface NSObject (Logger)
-(void)logSelf;
@end


// mylib.m
void useMyLib(){
    NSLog(@"do nothing, just for make mylib linked");
}


@implementation NSObject (Logger)
-(void)logSelf{
    NSLog(@"self is:%@", [self description]);
}
@end

dan jika kita memanggil useMyLib (); di mana saja di proyek App maka di kelas apa pun kita dapat menggunakan metode kategori logSelf;

[self logSelf];

Dan lebih banyak blog bertema:

http://t-machine.org/index.php/2009/10/13/how-to-make-an-iphone-static-library-part-1/

http://blog.costan.us/2009/12/fat-iphone-static-libraries-device-and.html

Vladimir
sumber
8
Catatan teknologi Apple tampaknya telah dimodifikasi untuk mengatakan "Untuk mengatasi masalah ini, target yang terhubung dengan perpustakaan statis harus meneruskan opsi -ObjC ke linker." yang merupakan kebalikan dari apa yang dikutip di atas. Kami baru saja mengonfirmasi bahwa Anda harus menyertakan saat menautkan aplikasi dan bukan perpustakaan itu sendiri.
Ken Aspeslagh
Menurut doc developer.apple.com/library/mac/#qa/qa1490/_index.html , kita harus menggunakan flag -all_load atau -force_load. Seperti yang disebutkan, tautan memang memiliki bug di Aplikasi 64bit Mac dan Aplikasi iPhone. "Penting: Untuk aplikasi 64-bit dan iPhone OS, ada bug penghubung yang mencegah -ObjC dari memuat file objek dari pustaka statis yang hanya berisi kategori dan tidak ada kelas. Solusinya adalah dengan menggunakan flag -all_load atau -force_load."
Robin
2
@ Ken Aspelagh: Terima kasih, saya punya masalah yang sama. Bendera -ObjC dan -all_load perlu ditambahkan ke aplikasi itu sendiri , bukan perpustakaan.
titaniumdecoy
3
Jawaban yang bagus, meskipun pendatang baru untuk pertanyaan ini harus mencatat bahwa itu sudah ketinggalan zaman. Lihat jawaban tonklon stackoverflow.com/a/9224606/322748 (all_load / force_load tidak diperlukan lagi)
Jay Peyer
Saya terjebak pada hal-hal ini selama hampir setengah jam dan dengan coba-coba saya baru saja berhasil. Bagaimanapun terima kasih. Jawaban ini bernilai +1 dan Anda mendapatkannya !!!
Deepukjayan
118

Jawaban dari Vladimir sebenarnya cukup bagus, namun, saya ingin memberikan sedikit latar belakang pengetahuan di sini. Mungkin suatu hari seseorang menemukan balasan saya dan mungkin merasa terbantu.

Kompiler mengubah file sumber (.c, .cc, .cpp, .m) menjadi file objek (.o). Ada satu file objek per file sumber. File objek berisi simbol, kode, dan data. File objek tidak dapat langsung digunakan oleh sistem operasi.

Sekarang ketika membangun perpustakaan dinamis (.dylib), kerangka kerja, bundel yang dapat dimuat (.bundle) atau biner yang dapat dieksekusi, file objek ini dihubungkan bersama oleh linker untuk menghasilkan sesuatu yang sistem operasi anggap "dapat digunakan", misalnya sesuatu yang dapat langsung memuat ke alamat memori tertentu.

Namun ketika membangun perpustakaan statis, semua file objek ini hanya ditambahkan ke file arsip besar, maka ekstensi perpustakaan statis (.a untuk arsip). Jadi file .a tidak lebih dari arsip file objek (.o). Pikirkan arsip TAR atau arsip ZIP tanpa kompresi. Ini hanya lebih mudah untuk menyalin satu file .a sekitar dari sejumlah file .o (mirip dengan Jawa, di mana Anda mengemas file .class ke dalam arsip .jar untuk distribusi mudah).

Saat menautkan biner ke pustaka statis (= arsip), tautan akan mendapatkan tabel semua simbol dalam arsip dan memeriksa simbol mana yang dirujuk oleh binari. Hanya file objek yang mengandung simbol yang direferensikan yang sebenarnya dimuat oleh linker dan dianggap oleh proses penautan. Misalnya jika arsip Anda memiliki 50 file objek, tetapi hanya 20 yang mengandung simbol yang digunakan oleh biner, hanya 20 yang dimuat oleh linker, 30 lainnya sepenuhnya diabaikan dalam proses penautan.

Ini berfungsi cukup baik untuk kode C dan C ++, karena bahasa-bahasa ini mencoba melakukan sebanyak mungkin pada waktu kompilasi (meskipun C ++ juga memiliki beberapa fitur runtime-only). Obj-C, bagaimanapun, adalah jenis bahasa yang berbeda. Obj-C sangat tergantung pada fitur runtime dan banyak fitur Obj-C sebenarnya hanya fitur runtime. Kelas Obj-C sebenarnya memiliki simbol yang sebanding dengan fungsi C atau variabel global C (setidaknya dalam runtime Obj-C saat ini). Linker dapat melihat apakah suatu kelas direferensikan atau tidak, sehingga dapat menentukan kelas yang digunakan atau tidak. Jika Anda menggunakan kelas dari file objek di perpustakaan statis, file objek ini akan dimuat oleh linker karena linker melihat simbol sedang digunakan. Kategori adalah fitur runtime-only, kategori bukan simbol seperti kelas atau fungsi dan itu juga berarti penghubung tidak dapat menentukan apakah suatu kategori sedang digunakan atau tidak.

Jika tautan memuat file objek yang berisi kode Obj-C, semua bagian Obj-C selalu menjadi bagian dari tahap penautan. Jadi jika file objek yang berisi kategori dimuat karena simbol apa pun dari itu dianggap "sedang digunakan" (baik itu kelas, baik itu fungsi, baik itu variabel global), kategori tersebut akan dimuat juga dan akan tersedia saat runtime . Namun jika file objek itu sendiri tidak dimuat, kategori di dalamnya tidak akan tersedia saat runtime. File objek yang berisi hanya kategori yang tidak pernah dimuat karena mengandung tidak ada simbol linker akan pernah mempertimbangkan "digunakan". Dan inilah keseluruhan masalahnya di sini.

Beberapa solusi telah diajukan dan sekarang setelah Anda tahu bagaimana semua ini bekerja bersama, mari kita lihat lagi solusi yang diusulkan:

  1. Salah satu solusinya adalah menambahkan -all_loadpanggilan tautan. Apa yang sebenarnya akan dilakukan oleh bendera tautan? Sebenarnya itu memberitahu linker berikut ini " Muat semua file objek dari semua arsip terlepas dari apakah Anda melihat simbol yang digunakan atau tidak '. Tentu saja, itu akan berhasil; tetapi juga dapat menghasilkan biner yang agak besar.

  2. Solusi lain adalah menambahkan -force_loadpanggilan tautan termasuk jalur ke arsip. Bendera ini berfungsi persis seperti -all_load, tetapi hanya untuk arsip yang ditentukan. Tentu saja ini akan berhasil juga.

  3. Solusi paling populer adalah menambahkan -ObjCpanggilan tautan. Apa yang sebenarnya akan dilakukan oleh bendera tautan? Bendera ini memberi tahu penghubung " Muat semua file objek dari semua arsip jika Anda melihat bahwa mereka mengandung kode Obj-C ". Dan "kode Obj-C" termasuk kategori. Ini akan bekerja juga dan tidak akan memaksa memuat file objek yang tidak mengandung kode Obj-C (ini masih hanya dimuat sesuai permintaan).

  4. Solusi lain adalah pengaturan build Xcode yang agak baru Perform Single-Object Prelink. Apa yang akan dilakukan pengaturan ini? Jika diaktifkan, semua file objek (ingat, ada satu file per sumber) digabung bersama menjadi file objek tunggal (yang bukan penautan nyata, maka nama PreLink ) dan file objek tunggal ini (kadang-kadang juga disebut "objek master" file ") kemudian ditambahkan ke arsip. Jika sekarang simbol dari file objek master dianggap sedang digunakan, seluruh file objek master dianggap sedang digunakan dan dengan demikian semua bagian Objective-C selalu dimuat. Dan karena kelas adalah simbol normal, cukup menggunakan satu kelas dari pustaka statis untuk mendapatkan semua kategori.

  5. Solusi terakhir adalah trik yang ditambahkan Vladimir di akhir jawabannya. Tempatkan " simbol palsu " ke file sumber apa pun yang hanya menyatakan kategori. Jika Anda ingin menggunakan salah satu kategori saat runtime, pastikan Anda entah bagaimana mereferensikan simbol palsu pada waktu kompilasi, karena ini menyebabkan file objek dimuat oleh linker dan dengan demikian juga semua kode Obj-C di dalamnya. Misalnya itu bisa fungsi dengan badan fungsi kosong (yang tidak akan melakukan apa-apa ketika dipanggil) atau itu bisa menjadi variabel global yang diakses (misalnya globalintsetelah membaca atau sekali ditulis, ini sudah cukup). Tidak seperti semua solusi lain di atas, solusi ini menggeser kontrol tentang kategori mana yang tersedia saat runtime ke kode yang dikompilasi (jika ia ingin mereka ditautkan dan tersedia, ia mengakses simbol, jika tidak mengakses simbol dan linker akan mengabaikan Itu).

Itu semua orang.

Oh, tunggu, ada satu hal lagi:
Linker memiliki opsi bernama -dead_strip. Apa yang dilakukan opsi ini? Jika linker memutuskan untuk memuat file objek, semua simbol file objek menjadi bagian dari biner yang ditautkan, apakah mereka digunakan atau tidak. Misalnya file objek berisi 100 fungsi, tetapi hanya satu dari mereka yang digunakan oleh biner, semua 100 fungsi masih ditambahkan ke biner karena file objek baik ditambahkan secara keseluruhan atau tidak ditambahkan sama sekali. Menambahkan file objek sebagian biasanya tidak didukung oleh tautan.

Namun, jika Anda memberi tahu tautan ke "dead strip", tautan pertama akan menambahkan semua file objek ke biner, menyelesaikan semua referensi dan akhirnya memindai biner untuk simbol yang tidak digunakan (atau hanya digunakan oleh simbol lain yang tidak di menggunakan). Semua simbol yang ditemukan tidak digunakan kemudian dihapus sebagai bagian dari tahap optimasi. Dalam contoh di atas, 99 fungsi yang tidak digunakan dihapus lagi. Ini sangat berguna jika Anda menggunakan opsi seperti -load_all, -force_loadatau Perform Single-Object Prelinkkarena opsi ini dapat dengan mudah meledakkan ukuran biner secara dramatis dalam beberapa kasus dan pengupasan mati akan menghapus kode dan data yang tidak digunakan lagi.

Dead stripping berfungsi sangat baik untuk kode C (mis. Fungsi yang tidak digunakan, variabel dan konstanta dihapus seperti yang diharapkan) dan juga bekerja cukup baik untuk C ++ (mis. Kelas yang tidak digunakan dihapus). Itu tidak sempurna, dalam beberapa kasus beberapa simbol tidak dihapus meskipun akan baik-baik saja untuk menghapusnya, tetapi dalam kebanyakan kasus itu berfungsi dengan cukup baik untuk bahasa-bahasa ini.

Bagaimana dengan Obj-C? Lupakan saja! Tidak ada stripping mati untuk Obj-C. Karena Obj-C adalah bahasa fitur runtime, kompiler tidak dapat mengatakan pada waktu kompilasi apakah simbol benar-benar digunakan atau tidak. Misalnya kelas Obj-C tidak digunakan jika tidak ada kode yang langsung merujuknya, benar? Salah! Anda dapat secara dinamis membuat string yang berisi nama kelas, meminta pointer kelas untuk nama itu dan mengalokasikan kelas secara dinamis. Misalnya bukannya

MyCoolClass * mcc = [[MyCoolClass alloc] init];

Saya juga bisa menulis

NSString * cname = @"CoolClass";
NSString * cnameFull = [NSString stringWithFormat:@"My%@", cname];
Class mmcClass = NSClassFromString(cnameFull);
id mmc = [[mmcClass alloc] init];

Dalam kedua kasus mmcadalah referensi ke objek dari kelas "MyCoolClass", tetapi tidak ada referensi langsung ke kelas ini dalam sampel kode kedua (bahkan tidak nama kelas sebagai string statis). Semuanya terjadi hanya saat runtime. Dan itu meskipun kelas sebenarnya adalah simbol nyata. Bahkan lebih buruk untuk kategori, karena mereka bahkan bukan simbol nyata.

Jadi jika Anda memiliki pustaka statis dengan ratusan objek, namun sebagian besar binari Anda hanya memerlukan beberapa di antaranya, Anda dapat memilih untuk tidak menggunakan solusi (1) hingga (4) di atas. Kalau tidak, Anda berakhir dengan binari yang sangat besar yang berisi semua kelas ini, meskipun sebagian besar dari mereka tidak pernah digunakan. Untuk kelas Anda biasanya tidak memerlukan solusi khusus sama sekali karena kelas memiliki simbol nyata dan selama Anda mereferensikannya secara langsung (tidak seperti dalam contoh kode kedua), tautan akan mengidentifikasi penggunaannya dengan cukup baik. Namun untuk kategori, pertimbangkan solusi (5), karena memungkinkan untuk hanya memasukkan kategori yang benar-benar Anda butuhkan.

Misalnya, jika Anda menginginkan kategori untuk NSData, misalnya menambahkan metode kompresi / dekompresi, Anda akan membuat file header:

// NSData+Compress.h
@interface NSData (Compression)
    - (NSData *)compressedData;
    - (NSData *)decompressedData;
@end

void import_NSData_Compression ( );

dan file implementasi

// NSData+Compress
@implementation NSData (Compression)
    - (NSData *)compressedData 
    {
        // ... magic ...
    }

    - (NSData *)decompressedData
    {
        // ... magic ...
    }
@end

void import_NSData_Compression ( ) { }

Sekarang pastikan bahwa di mana saja dalam kode Anda import_NSData_Compression()dipanggil. Tidak masalah di mana namanya atau seberapa sering disebut. Sebenarnya itu tidak benar-benar harus dipanggil sama sekali, itu sudah cukup jika linker berpikir demikian. Misalnya Anda dapat meletakkan kode berikut di mana saja di proyek Anda:

__attribute__((used)) static void importCategories ()
{
    import_NSData_Compression();
    // add more import calls here
}

Anda tidak perlu memanggil importCategories()kode Anda, atribut akan membuat kompiler dan linker percaya bahwa itu disebut, bahkan jika tidak.

Dan tip terakhir:
Jika Anda menambah -whyloadpanggilan tautan terakhir, penghubung akan mencetak dalam log build file objek mana dari perpustakaan mana ia memuat karena simbol yang digunakan. Ini hanya akan mencetak simbol pertama yang dianggap digunakan, tetapi itu tidak selalu merupakan satu-satunya simbol yang digunakan dalam file objek itu.

Mecki
sumber
1
Terima kasih telah menyebutkan -whyload, mencoba men-debug mengapa linker melakukan sesuatu bisa sangat sulit!
Ben S
Ada opsi Dead Code Strippingdi Build Settings>Linking. Apakah sama dengan -dead_stripmenambahkan Other Linker Flags?
Xiao
1
@Sean Ya, sama saja. Hanya membaca "Bantuan Cepat" yang ada untuk setiap pengaturan membangun, jawabannya ada di sana: postimg.org/image/n7megftnr/full
Mecki
@Mecki Terima kasih. Saya mencoba untuk menyingkirkan -ObjC, jadi saya mencoba peretasan Anda tetapi komplain "import_NSString_jsonObject()", referenced from: importCategories() in main.o ld: symbol(s) not found. Saya memasukkan import_NSString_jsonObjectFramework tertanam saya bernama Utility, dan menambahkan #import <Utility/Utility.h>dengan __attribute__pernyataan di akhir saya AppDelegate.h.
Xiao
@Sean Jika linker tidak dapat menemukan simbol, Anda tidak menautkan ke perpustakaan statis yang berisi simbol. Hanya mengimpor file ah dari suatu framework tidak akan membuat tautan Xcode terhadap framework tersebut. Kerangka kerja harus secara eksplisit ditautkan ke dalam tautan dengan kerangka kerja fase pembangunan. Anda mungkin ingin membuka pertanyaan sendiri untuk masalah penautan Anda, menjawab dalam komentar itu rumit dan Anda juga tidak bisa memberikan informasi seperti membangun log output.
Mecki
24

Masalah ini telah diperbaiki di LLVM . Perbaikan dikirimkan sebagai bagian dari LLVM 2.9 Versi Xcode pertama yang berisi perbaikan adalah Xcode 4.2 pengiriman dengan LLVM 3.0. Penggunaan -all_loadatau -force_loadtidak lagi diperlukan ketika bekerja dengan XCode 4.2 -ObjC masih diperlukan.

tonklon
sumber
Apa kau yakin tentang ini? Saya sedang mengerjakan proyek iOS menggunakan Xcode 4.3.2, kompilasi dengan LLVM 3.1 dan ini masih menjadi masalah bagi saya.
Ashley Mills
Ok, itu sedikit tidak tepat. The -ObjCflag masih diperlukan dan akan selalu. Solusinya adalah penggunaan -all_loadatau -force_load. Dan itu tidak diperlukan lagi. Saya memperbaiki jawaban saya di atas.
tonklon
Apakah ada kerugian untuk menyertakan flag -all_load (bahkan jika itu tidak perlu)? Apakah itu mempengaruhi waktu kompilasi / peluncuran dengan cara apa pun?
ZS
Saya bekerja dengan Xcode Versi 4.5 (4G182) dan flag -ObjC memindahkan kesalahan pemilih yang tidak dikenal dari ketergantungan pihak ke-3. Saya mencoba menggunakan apa yang tampak seperti kedalaman runtime Objective C: "- [__ NSArrayM map :]: pemilih yang tidak dikenal dikirim ke instance ... ". Ada petunjuk?
Robert Atkins
16

Inilah yang perlu Anda lakukan untuk menyelesaikan masalah ini sepenuhnya saat kompilasi pustaka statis Anda:

Pergi ke Pengaturan Xcode Build dan atur Perform Single-Object Prelink ke YES atau GENERATE_MASTER_OBJECT_FILE = YESdalam file konfigurasi build Anda.

Secara default, linker menghasilkan file .o untuk setiap file .m. Jadi kategori mendapat file .o yang berbeda. Ketika tautan melihat file .o perpustakaan statis, itu tidak membuat indeks semua simbol per kelas (Runtime akan, tidak peduli apa).

Arahan ini akan meminta linker untuk mengemas semua objek menjadi satu file .o besar dan dengan ini memaksa linker yang memproses perpustakaan statis untuk mendapatkan indeks semua kategori kelas.

Harapan yang mengklarifikasi itu.

amosel
sumber
Ini memperbaikinya bagi saya tanpa harus menambahkan -ObjC ke target penautan.
Matthew Crenshaw
Setelah memperbarui ke versi terbaru dari perpustakaan BlocksKit , saya harus menggunakan pengaturan ini untuk memperbaiki masalah (saya sudah menggunakan flag -ObjC tetapi masih melihat masalah).
rakmoh
1
Sebenarnya jawaban Anda kurang tepat. Saya tidak "meminta linker untuk mengemas semua kategori dari kelas yang sama menjadi satu file .o", ia meminta linker untuk menautkan semua file objek (.o) ke dalam file objek tunggal yang besar sebelum membuat perpustakaan statis dari mereka / itu. Setelah simbol apa pun dirujuk dari perpustakaan, semua simbol dimuat. Namun, ini tidak akan berfungsi jika tidak ada simbol yang dirujuk (mis. Jika tidak akan berfungsi jika hanya ada kategori di perpustakaan).
Mecki
Saya tidak berpikir ini akan berfungsi jika Anda menambahkan kategori ke kelas yang ada, seperti NSData.
Bob Whiteman
Saya juga mengalami kesulitan menambahkan kategori ke kelas yang ada. Plugin saya tidak dapat mengenalinya saat dijalankan.
David Dunham
9

Salah satu faktor yang jarang disebutkan setiap kali diskusi penghubung pustaka statis muncul adalah kenyataan bahwa Anda juga harus memasukkan kategori itu sendiri dalam fase pembuatan-> menyalin file dan mengkompilasi sumber pustaka statis itu sendiri .

Apple juga tidak menekankan fakta ini dalam Menggunakan Perpustakaan Statis mereka yang baru-baru ini diterbitkan di iOS .

Saya menghabiskan sepanjang hari mencoba segala macam variasi -objC dan -all_load dll. Tapi tidak ada yang keluar dari itu .. pertanyaan ini membawa masalah itu menjadi perhatian saya. (jangan salah paham .. Anda masih harus melakukan hal -objC .. tapi ini lebih dari itu).

juga tindakan lain yang selalu membantu saya adalah bahwa saya selalu membangun perpustakaan statis yang disertakan terlebih dahulu sendiri .. maka saya membangun aplikasi terlampir ..

abbood
sumber
-1

Anda mungkin perlu memiliki kategori di tajuk "publik" pustaka statis: #import "MyStaticLib.h"

christo16
sumber