2011-02-07 16 views
5
Objective-C id olarak

bir typedef:Amaç-° C; işaretçi olmadan kimlik yerine typedef objc_object;

typedef struct objc_object { 
    Class isa; 
} *id; 

bir değişken, sözgelimi beyan (ve initialize) olabilir Yani şöyle:

// using id 
id po_one = @"one"; 

İyi bir şekilde derler.

Ben kendi düzeni benim türlerini isim ve beri böyle (nesne için O ile) kendi typedef eklemek istediğiniz typedef id içinde zımni işaretçi sevmediğim tarihi: bir değişken Yani

typedef struct objc_object O; 

bildirimi şöyle olabilir:

// using O 
O * po_two = @"two"; 

Bu bir uyarı ile derlenir:

Uyumsuz işaretçi türünden başlatma

Ben yazım hatalarını anladığım kadarıyla ikincisi,

// using struct objc_object 
struct objc_object * po_three = @"three"; 

değerine eşit olmalıdır. Uyarılar olmadan derlemek

po_two = po_one; 
po_two = po_three; 

hem:

O şaşırtıcı.

Denedim Yani: (Ben önlemek istiyorum tam olarak bir şey olmak - yani sadece deney nedenlerle) işaretçisi eklerseniz o uyarı olmadan çalışıp çalışmadığını kontrol etmek

typedef struct objc_object * PO; 

görmek ister dışında bir typedef yapı tanımı, yapı tanımındaki bir yazım kuralına farklı şekilde çalışır (bu durumda id'nin tanımı).

Bu da iyi çalışıyor. Ben kullanırsanız

:

#define O struct objc_object 

kullanarak yapı Ç tekrar uyarı olmadan derler.

Ancak mümkün olduğunda tanımlamalar yerine typedefs kullanmayı tercih ederim.

Şaşkınım. Typedefs ile yanlış anlaşılma nedir?

+0

Hangi derleyici? – JeremyP

+1

Ayrıca, "O *" yerine "NSObject *" işlevini kullanabilirsiniz. NSObject * po_two = @ "two"; ', çoğu durumda. –

cevap

2

Derleyicilerden bir uzman değilim, muhtemelen gerçek bir uzman size daha iyi bir cevap verebilir. Her halükarda, bir derleyicinin denetimi yazdığı zaman, bilgimden yola çıkarak, bu denetimi, tüm olası veri türü yapıları için bir çeşit tablo oluşturan "ayrıştırma ağacı" na dayandırır ve iki tanımın aynı satırın işaret edip etmediğini kontrol eder. masada. Böylece bu tablodan semboller ve tip tanımları alıp bunları karşılaştırarak çalışır. Artık "struct objc_object" bu veri yapılarından biridir.Daha sonra, kimlik tanımlandığında, başka bir girdi oluşturur: "id -> struct objc_object *". po_three tanımı aynı referansa yol açar: "struct objc_object *" (infact "=" en düşük önceliğe sahiptir). Aynı po_four için de geçerlidir, çünkü PO, aynı referansa göre tanımlamaya başlar (PO -> struct objc_object *). #define ile tanımı kullandığınızda, önişleme sayesinde hala "struct objc_object *" ifadesini kullanıyorsunuz demektir.

O * po_two = @"two"
'u kullanırken aslında "id" (@ "iki"), "struct objc_object *" ve "struct objc_object" öğelerinin bir işaretçisi olan bir türe eşleşmeye çalışıyorsunuzdur. mantıksal olarak aynıdırlar, aynı referans tablosuna götürmezler. Bunun nedeni, "O" türünün henüz tanımlanmış olmasıdır, bu nedenle po_two, sembol tablosunda "O" ve "O -> struct objc_object" öğelerine işaretçi olarak saklanır. Ve bu da uyarının nedeni: po_two, "iki" den farklı bir şeye işaret ediyor.

Merakım var: "nm" kullanarak sembol tablosunu çizmeye çalıştınız mı?

+0

Uyumsuz tablo girişleri ile iyi bir tahmin olabilir. nm'yi denedim ancak yararlı bilgiler vermiyor. Ayrıca hata ayıklayıcı aynı türlerini gösterir - en azından başlatmadan sonra. Şu anki tahminim şu ki, herhangi bir işaretçinin kimliğe dönüştürülmesini sağlayan gcc'ye yerleşik bir kesmek var. Ama belki de basit c tipi kurallar (ki bunlarda, ID ve O * için eşdeğer türlere yol açacak) düşünülmüştür ve bu nedenle yazım hatası uyarıda bulunur. – carpetemporem

+0

Evet, bu po_two = po_three'deki eksik uyarıyı açıklayabilir. – viggio24