Xcode'da "Bağlı Çerçeveler" yerine "gömülü ikili dosyalar" ne zaman kullanılmalıdır?


140

Bağlantı İkili VS kütüphaneleri ile Gömme Çerçeveleri'nde açıklandığı gibi bu iki seçenek arasındaki fark hakkında iyi bir soru var .

İkisini de kullanmak için seçeneklerimiz var gibi görünüyor, sadece hangi durumda gömülü ikili dosyaları daha iyi veya bağlantılı bir çerçeveden daha iyi kullanmamız gerektiğini merak ediyoruz?

Daha açık bir şekilde ele almak için sağlam örnekler var mı? Teşekkürler


Yanıtlar:


239

Bağladığınız soru, İkili Kitaplıklarıyla Bağlantılandır "işlevselliğine, katıştırılmış bir ikili dosyadan biraz farklıdır.

"İkili Kitaplıklarıyla Bağla", bağlantıyla ilgili olarak beklediğiniz şey anlamına gelir: İkili dosya, statik kitaplık mı, dinamik kitaplık mı yoksa çerçeve mi olursa olsun, derleme işleminden sonraki bağlantı zamanında nesne kodunuza bağlanır.

Statik bir kitaplıkla bağlantıyı düşündüğünüzde, ne olduğu oldukça açıktır: bağlayıcı , kodu kitaplıktan (örn. ) Çıktı ikili dosyaya kopyalarlibFoo.a . Çıktı dosyanızın boyutu büyür, ancak çalışma zamanında harici bağımlılıkları çözmeniz gerekmez. Programınızın çalışması için gereken her şey (statik kitaplıkla ilgili olarak) oluşturulduktan sonra hazır olur.

Dinamik bir kitaplıkla (.dylib veya sistem tarafından sağlanan çerçeve), beklediğiniz kitaplığın, programınızı çalıştırdığınızda sistemin dinamik kitaplık yükleyici yolunda bir yerde bulunmasıdır. Bu şekilde, tüm üçüncü taraf harici kütüphaneleri ikili dosyaya kopyalama yükünüz olmaz ve bu kütüphaneye bağlanan bir bilgisayardaki tüm farklı programlar onu bulabilir, bu da en az disk alanı kazandırır, aynı zamanda sistemin kütüphaneleri nasıl ve nerede önbelleğe aldığına bağlı olarak potansiyel olarak bellek alanı.

Bir çerçeve, dinamik bir kitaplığa çok benzer, ancak dizin yapısında (resimler, ses, diğer çerçeveler vb.) Kaynaklar içerebilir. Eğer sadece bu yüzden bir çerçeveye bağlantıya sahip olabilir, böylece bu durumda basit bir statik kitaplık veya .dylib dosya kesmeyecek o düzgün çalışmasına gerekenleri bulabilirsiniz.

Üçüncü taraf bir çerçeveye bağladığınızda (github'dan indirip kendiniz oluşturduğunuz bir şey söyleyin), üzerinde çalışmayı düşündüğünüz sistemde bulunmayabilir. Bu durumda, yalnızca çerçeveye bağlanmakla kalmaz, aynı zamanda "Çerçeveleri Kopyala" aşamasını kullanarak da uygulama paketinizin içine yerleştirirsiniz. Programınız çalıştığında, çalışma zamanı-bağlayıcısı (çözümleyici olarak da bilinir) sistem yükleyici yoluna ek olarak paketinizin içine bakar, katıştırılmış çerçeveyi bulur ve uygulamanızın çalışması için gereken koda sahip olmasını sağlar.

Son olarak, düzgün bir şekilde "gömülü ikili" olan şey, her ikisi de uygulama paketinize bir Kopya Dosyaları Aşaması aracılığıyla katıştırdığınız ve belki de bir çağrı popen()veya benzeri bir yöntemle yürüttüğünüz bir yürütülebilir dosyadır . Gömülü ikili programınız tarafından çağrılabilir, ancak programla bağlantılı değildir. Tamamen harici bir varlıktır ( /bindizindeki programlar gibi ).

Uygulamada, sistem tarafından sağlanan kütüphaneler ve çerçeveler için bunlara bağlanacaksınız ve tek yapmanız gereken bu.

Oluşturduğunuz, gömülü kaynak gerektirmeyen (yani bir çerçeve olmasını gerektirmeyen) bir kitaplığı bağlamanız gerekiyorsa, statik bir kitaplığa bağlanabilirsiniz. Programınızda aynı kütüphane kodunu kullanmak isteyen birden fazla modül olduğunu fark ederseniz, onu bir çerçeveye veya dinamik kütüphaneye dönüştürmek ve bunlara bağlantı kurmak yerden tasarruf sağlayabilir ve kullanışlı olabilir (özellikle bellek kullanımı endişe kaynağıysa).

Son olarak, çerçeveler yalnızca kaynakları değil, başlık ve / veya lisans dosyalarını da içerebilir. Bu dosyaları iletmek için bir çerçeve kullanmak aslında uygun bir dağıtım mekanizmasıdır, bu nedenle çoğu zaman bir çerçeveyi dahil etmek isteyebilirsiniz, böylece bu şeyler ikili dosyanızla birlikte etiketleyebilir (yani lisans gereksinimleri bunu zorunlu kılabilir).

--- DÜZENLE ---

Adam Johns aşağıdaki soruyu yorum olarak gönderdi:

Bu harika bir cevap. Yine de biraz kafam karıştı. İkili dosyayı kendiniz yürütmek ne demektir? Sadece gömülü çerçevenin kodunu kullanmak mı istiyorsunuz? Popen () 'dan bahsettiğinizi biliyorum, ancak uygulamamın popen () çağırdığını söylüyorsunuz? Bunun ne anlama geldiğini gerçekten bilmiyorum.

Katıştırılmış bir ikili , dosya yerine yürütülebilir bir komut satırı aracı olmasına rağmen, paketinizdeki ses dosyası veya görüntü gibi başka bir kaynak dosyası olduğunu söylüyorum . popen()Fonksiyonu ( man popenBaşka eden programın rasgele programları yürütmek sağlar yaklaşık terminal den fazla okumak için). system()Fonksiyon başka bir yoludur. Başkaları da var ve burada gömülü bir ikiliyi daha anlaşılır hale getirebilecek tarihsel bir örnek vereceğim:

Muhtemelen bildiğiniz gibi, Mac OS X'te bir uygulama başlattığınızda mevcut kullanıcının kullanıcı kimliğiyle başlatılır. En yaygın yüklemelerde, adminkullanıcı kimliği verilen varsayılan Masaüstündeki kullanıcıdır 501.

Unix tabanlı işletim sistemlerinde yalnızca rootkullanıcı (kullanıcı kimliği 0) tüm dosya sistemine tam erişime sahiptir. Bazen Masaüstü kullanıcısı tarafından başlatılan bir yükleyici programının dosyaları ayrıcalıklı bir dizine (örneğin sürücüler) yüklemesi gerekebilir. Bu durumda, uygulama programının bu ayrıcalıklı rootdizinlere yazabilmesi için kullanıcıya ayrıcalıklarını artırması gerekir .

OS X 10.7 aracılığıyla işletim sistemlerinde bunu kolaylaştırmak için Apple, Yetkilendirme Hizmetleri API'sında AuthorizationExecuteWithPrivileges () işlevini sağlamıştır (bu artık kullanımdan kaldırılmıştır, ancak yine de yararlı bir örnektir).

AuthorizationExecuteWithPrivileges()argüman olarak yürütmek için bir komut satırı aracının yolunu aldı root. Komut satırı aracı, yükleme mantığınızı çalıştırmak için yazdığınız yürütülebilir bir kabuk komut dosyası veya derlenmiş bir ikili dosyadır. Bu araç, diğer tüm kaynak dosyaları gibi uygulama paketinizin içine yüklenmiştir.

İşletim sistemi çağrıldığında, kullanıcı şifresini isteyen bir yetkilendirme iletişim kutusu açar (bunu daha önce görmüştünüz!) Ve girildiğinde programı rootuygulamanızın adına uygular. Bu işlem sadece popen()kendinizle bir program yürütmeye benzer , ancak popen()tek başına size ayrıcalık yükseltme avantajı sağlamaz.


62
Bunları nasıl biliyorsun?
Ian Warburton

56
@IanWarburton Apple işletim sistemlerini 20 yıldan fazla bir süredir programlıyorum ve burada birkaç tane çöp topladım. :)
par

1
@JustAMartin Yani link, bir kopya dosyaları aşaması yoluyla da yerleştirmeniz gerektiği doğrudur (aksi takdirde nasıl kullanırsınız?). Üçüncü taraf çerçevesi veya gömülü ikili dosya kullanmanın amacı, kuruluşun sağladığı kodu yürütmektir. Gömülü bir ikili dosya ile bağlantı yoktur. Çalışma zamanında, ikili dosyaya bir yol oluşturup manuel olarak yürütün. Bir çerçeveyle, derleme zamanı bağlayıcısı uygulamanızı oluşturduğunuzda bağlar, ardından (3. taraf bir çerçeve ise) bir kopya dosyaları aşaması aracılığıyla gömer ve son olarak çalışma zamanı bağlayıcısı uygulamanızı çalıştırdığınızda tekrar bağlar .
par

1
@JustAMartin'e cevap verdiğiniz şeyler biraz belirsiz. Üçüncü taraf çerçevesi veya gömülü ikili dosya kullanmanın amacı, kuruluşun sağladığı kodu yürütmektir. Günümüzde Gömülü ikili dosyalar üçüncü taraf çerçevesi de olabilir. Burada ne demek istediğini anlamaya çalışıyorum ... AFA anladım, gömülü ikili anlamına gelir, gömülü çerçevenin ayrı bir ikili App paketinde tanıtılacak Ve Ve aynı çerçeveyi bağlarsanız, bunu aynı ikili dosyaya koyacaktır app. Lütfen beni düzeltin Eğer yanılıyorsam ...
hariszaman

1
Belki de gömülü bir çerçeve yükleyecek yeni Xcode büyüsü var. Bu işlevselliğe ihtiyaç duyduğumdan beri bir süredir. Daha neler olup bittiğini keşfetmek istiyorsanız, lütfen SO'ya yeni bir soru gönderin.
par

35

Kısacası,

  • sistem kütüphaneleri;
  • 3. parti kütüphaneleri, onları gömün.

neden?

  • sistem kitaplıklarını gömmeye çalışırsanız, açılır listede bulamazsınız;
  • 3. taraf kitaplıkları bağlarsanız büyük olasılıkla bir kilitlenme olur.

7

Bu Dependencyyönetimin bir parçasıdır [Hakkında]

Lütfen sekmedeki Xcode 11yalnızca Frameworks, Libraries, and Embedded Contentbölümün bulunduğunu unutmayınGeneral

Bağlantı İkili

Build Phases -> Link Binary With Librariesbir aynasıdır General -> Linked Frameworks and Libraries.

Statik Kütüphane ve Çerçeve

Static Library or Static FrameworkBu bölüme bir eklerseniz Frameworks grup [Hakkında] ( Project Navigator -> <workspace/project> -> Frameworks) grubunda görünür ve projenize bunun için bir referans eklenir. Sonra tarafından kullanılacak Static Linker. Static Linkerderleme zamanında kütüphanedeki tüm kodu yürütülebilir nesne dosyasına ekler / kopyalar . Static linkerile birlikte çalışırBuild Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths. static frameworkBu bölüme a eklemezseniz derleme hatası alırsınız [Böyle bir modül yok]

İkili göm

Statik Kütüphane ve Statik Çerçeve

Gömme a için bir anlam ifade etmez Static Libraryve Static Frameworkonlardan gelen semboller çalıştırılabilir ikili dosyaya derlenir. Xcode static library, Göm bölümünün altına bir bırakmanıza izin vermez .

Dinamik Çerçeve

Build Phases -> Embed Frameworksbir aynasıdır General -> Embedded Binaries. Gömme aslında çerçevenin bir kopyasını uygulama paketinize ekler . Bir çerçeve ilave edilir, sonuç olarak, / uzaklaştırılarak Embedotomatik uzaklaştırılarak / eklenecektir bölüm Linkedbölüm. Varsayılan olarak paketin klasörüdür, Frameworksancak Destinationalanı kullanarak değiştirebilirsiniz . Ayrıca bir Subpath.

Dynamic linker :dyldEn yük veya çalışma zamanında bulmaya çalışacağız gömülü çerçeveyi kullanan @rpath[Hakkında] o hata oluşacaktır bulunmazsa [dyld: Kütüphane yüklenmemiş]

[Link ve Embed kullanıldığında]

[Kelime]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.