2009-12-15 8 views
7

Hiçbir fikrim neden ettik ama vesilesiyle bazı düzeltmek başardınız .m dosyası içine .h dosyadan #import "someClass.h" hareket ettirerek en önemlisiKakao: Başlıkta içe aktarma ile ana dosyada içe aktarma arasındaki fark nedir?

error expected specifier-qualifier-list before 'someClass' 

, hataları derleme. Bu aynı zamanda, başlıklar ile ilgili (bakış açımdan gizemli bir şekilde) karşılaştığım birkaç başka problemle de çalıştı.

Bazı üstünkörü googling cevabı "başlık dosyasına asla ithalat başlıklarını" yukarı döndü ve tavsiyeler durur yer zaten.

Ya ben tamamen bu kadar yaptıktan sonra veya bir yerden alışkanlığı aldım ama başlık başlıkları ithal amaçlanmış nerede olduğunu düşündüm. Açıkçası, ama kimse bana bunun neden olduğunu açıklayabilir ve üstbilgileri içe aktarmanın tercih edilen yolu nedir?

cevap

10

Eğer dahil ediyoruz sınıftan devralmasını sürece, başlıklarda başlıklarını içermemelidir. Bir nesneyi bir arabirim değişkeni olarak eklemeniz gerekiyorsa, bunun yerine @class yönergesini kullanmalısınız; Derleyiciye, tanımlayıcının bir sınıfa başvurduğunu söyler.

Bunun yerine, yalnızca uygulama dosyalarında ithalat başlıkları. Derleyici, örnek değişkenlerinizin nesneler için işaretçi olduğunu bilecektir, ancak üstbilgiyi ayrıştırırken nesnenin ayrıntılarını bilmez. Tek bilmesi gereken, onun bir sınıf olması. Derleyici, uygulama dosyanızı ayrıştırırken sınıfın yöntemlerini görebilir; Bu noktada, göndermekte olduğunuz mesajlara cevap verdiğini doğrulamak için sınıfa ihtiyaç duyar.


Güncelleme: Bazı sonradan sorulara yanıt cevabım güncellemek için gittiğini fakat Rob Napier has a good follow-up.

+1

"typedef" ve "protokoller" hakkında ne var? – Joost

+0

Bir öğretici veya bunu kullanan bir kod örneğini bilmek olmazdı? – gargantuan

13

John iyi bir tavsiye verir, ama burada Whys, wherefores ve istisnalarla ilgili biraz daha arka plandır. artan yapı süreleri ve dairesel bağımlılıkları kaçınma geliştirilmiş:

başlıklarını aktarmak başlıkları kaçınarak arkasında iki amacı vardır. Eğer B.h içine A.h ithalat ve C.h içine B.h içe aktarırsanız, o zaman A.h şey değiştirmek her zaman, sen C.mA.h tanımlanan şeylerden herhangi birinin hiçbir kullanır bile C.m yeniden derlemek zorunda. Bu, özellikle sık sık değişen başlıklara (gelişimin ilk aşamalarında yaygın olduğu gibi) sahipseniz, gerçekten korkunç ve gereksiz yapı karmaşasına yol açabilir.

İlk gol, ama utanç verici projeler için, kimin umurunda? Dört çekirdekli bir Pro'nuz var ve tam bir yapı birkaç dakika sürüyor, değil mi? Ama yine de ikinci sorun hakkında endişelenmeniz gerekiyor: Dairesel bağımlılıklar. A.h başvuru sınıfı B ve B.h başvuru sınıfı A. Bu aslında oldukça sık gerçekleşebilir ve oldukça masum bir sisteme girebilir. Bir koleksiyon nesnesi içerdiği nesnelerin türünü referans alabilir ve nesneler koleksiyon nesnesinin türüne başvuruda bulunabilir. Tek yapmanız gereken, bu türü alan veya döndüren bazı yöntemlerden kaynaklanmaktadır. Eğer diğer başlıkları ithal eden başlıklar varsa, bunun gerçekleşmesi ihtimali hızla birliğe yaklaşır. Yinelemeli içe aktarmalarla sona erer ve derleme zamanı hataları akıllara yol açabilir. "Ben , typdef tanımlandı biliyorum!İşte orada! Size bu başlığı ithal zaman henüz çözümlenen değildi! Ithal" Ama oluyor. Bu, yukarıda da hataya neden budur. Bu nedenle

, gerçi (çok yaklaşık kez inşa umurumda bile almak sahip siz), .... haricinde ... başlıklarını içine başlıkları ithal

Bazı başlıklar kaçınmalıdır. elbette senin üst sınıf. Dosyaları bir uygulamak @protocol veya tanımlamak o typedef kullanmak. Yani evet,

Ve sistem üstbilgileri hakkında ne var? ause churn, ve açıkçası, yinelemeli ithalata neden olmayacaklar, yani iyiler. Sistem üstbilgilerindeki öğeler için arkadaşlarınızın @class ileri bildirimlerini kullanmasını engellerim. Hiçbir şey için başlık değerinizin kullanıcısı üzerinde ekstra çalışma yaratır. İyi bir başlık hijyeni için, lütfen < köşeli parantez içinde > ve başlıklarınızı "tırnak işaretleri" içine getirin.

Bu, önemsiz bir soru değil, basit bir kuraldır: her zaman derleyicinin size izin vereceği zaman kullanıcı başlıklarını diğer kullanıcı başlıklarına aktarmayı önlemek.

+0

Bunun için çok teşekkür ederim. – gargantuan

0

Yalnızca başlığınızı uygulama dosyanızın içine değil, aynı zamanda bu sınıfı da kullanan başka dosyalara da dahil edersiniz. Başlığa tüm bağımlılıkları dahil ederseniz, yalnızca bu başlığı tanımlayan belirli bir sınıfı da içeren tüm diğer dosyalar kendileri de tüm bağımlılıkları içerecektir.

Bu yalnızca gürültülü değil, aynı zamanda kendilerini referans alan derslere sahip olduğunuzda da sorunlara yol açar. Her sınıfın diğerinden önce içe aktarılması gerekir, bu da önce bir tane ithal edilir ve sonra diğer sınıfın türünü bulamaz. Bu, deftere nakledilen şifreli hata iletisiyle sonuçlanır, temel olarak derleyicinin someClass türünü bulamadığı anlamına gelir. Uygulamanızın dosyası ve ileriye ilan Başlığınızda sınıfları ve türleri bu sorunları önleyebilirsiniz (@class, @protocol, vs kullanarak) içine ithalatı taşıyarak

.