SORU
23 Ocak 2012, PAZARTESİ


Id yerine örnektürü kullanmaya başlamak için faydalı olur mu?

Çınlama, görebildiğim kadarıyla, dönüş -alloc init türü id yerini alan bir kelime instancetype ekler.

id yerine instancetype kullanarak bir yararı var mı?

CEVAP
1 ŞUBAT 2013, Cuma


Evet, geçerli tüm durumlarda instancetype kullanarak faydaları vardır. Daha detaylı açıklamak, ama bana bu cesur açıklama ile başlayalım edeceğim: bir sınıf aynı sınıf örneği verir ne zaman ki uygun zaman instancetype,.

Aslında, burada Apple şimdi bu konuda ne diyor:

Kodunuzda, instancetype ile bir dönüş değeri uygun olarak id tekrarlarını değiştirmek. Bu genellikle init yöntemleri ve sınıf fabrika yöntemleri için geçerlidir. Olsa bile, derleyici otomatik olarak dönüştürür yöntemler ile başlayan “ayırma,” “başlatma” ya da “yeni” ve bir dönüş türü id dönmek instancetype değil mi dönüştürmek diğer yöntemler.Objective-C Kongre instancetype tüm yöntemler için açıkça yazmaktır.

Bu şekilde dışarı ile, bu hareket, iyi bir fikir değil neden açıklamama izin verin.

İlk olarak, bazı tanımlar:

 @interface Foo:NSObject
 - (id)initWithBar:(NSInteger)bar; // initializer
   (id)fooWithBar:(NSInteger)bar;  // class factory
 @end

Sınıf bir fabrika içinher zamaninstancetype kullanın. Derleyici otomatik olarak instancetype 25 *dönüştürmez. id genel bir nesnedir. Ama eğer bunu yaparsanız bir instancetype derleyici yöntemi döndürür bilir.

Budeğilakademik bir sorun. Örneğin, [[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData] Mac OS X üzerinde bir hata oluşturur (sadece)Birden fazla yöntem 'writeData:' hatalı sonuç bulundu, türü veya öznitelik parametresi . adlı . Nedeni de NSFileHandle ve NSURLHandle writeData: bulunur. [NSFileHandle fileHandleWithStandardOutput] döndürür beri bir id derleyici writeData: çağrıldığı ne belli değil.

Bu, ya da kullanmaya çalışmak gerekir:

[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData];

ya da:

NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
[fileHandle writeData:formattedData];

Tabii ki, daha iyi çözüm instancetype geri dönüş fileHandleWithStandardOutput bildirmektir. Sonra dökme veya Atama da gerekli değil.

(İOS, bu örnek NSFileHandle writeData: orada sağlar gibi, bir hata neden olmaz unutmayın. Mevcut diğer örnekler, UILayoutSupport ama NSString. NSUInteger CGFloat veren length gibi)

Başlatıcılar için, daha karmaşıktır. Bunu yazarken:

- (id)initWithBar:(NSInteger)bar

...derleyici bunun yerine, yazdığınız gibi

- (instancetype)initWithBar:(NSInteger)bar

Bu ARC için gerekliydi. Bu Çınlama Dil Uzantıları Related result types açıklanmıştır. Bu insanlar gerektiğini düşünüyorum ama instancetype kullanım için gerekli değil mi neden söyleyecektir. Bu cevap geri kalanı bu ilgilenir.

Üç avantajı vardır:

  1. Açık.Kodunuzu ne diyor, yerine başka bir şey yapıyor.
  2. Desen.Var olan fark etmez ne zaman iyi alışkanlıklar inşa ediyorsun.
  3. Tutarlılık.Daha okunabilir kılan kodunuzu, biraz tutarlılık kuruldu.

Açık

Yok yok doğruteknikinit instancetype iade etmeye yarar. Ama bu derleyici otomatik olarak instancetype 50 *dönüştürür olmasıdır. Bu espri üzerine güvenmek; init döndüren yazma yaparken bir id derleyici instancetype bir dönerse olarak yorumluyor.

Bueşdeğerderleyici için:

- (id)initWithBar:(NSInteger)bar;
- (instancetype)initWithBar:(NSInteger)bar;

Bu gözlerin denk değildir. En iyi ihtimalle, farkı görmezden ve göz gezdirmek için öğreneceksiniz.Bu görmezden gelmeyi öğrenmen gereken bir şey değil.

Desen

init ve diğer yöntemler ile fark var iken, yokbir fark olarak sınıf bir fabrika tanımlayın.

Bu iki eşdeğer değildir

  (id)fooWithBar:(NSInteger)bar;
  (instancetype)fooWithBar:(NSInteger)bar;

İkinci form istiyorum. Eğer bir kurucu dönüş türü olarak instancetype yazmak için kullanılan, hemen her zaman alırsınız.

Tutarlılık

Eğer hepsini bir araya getirirseniz, sonunda, hayal edin: init bir fonksiyon ve sınıf bir fabrika da istiyorum.

init id kullanıyorsanız, bu gibi bir kod ile bitirmek:

- (id)initWithBar:(NSInteger)bar;
  (instancetype)fooWithBar:(NSInteger)bar;

Ama eğer kullanıyorsanız instancetype Bu çıkıyor:

- (instancetype)initWithBar:(NSInteger)bar;
  (instancetype)fooWithBar:(NSInteger)bar;

Daha tutarlı ve daha okunabilir. Aynı şey geri döner, ve şimdi bu çok açık.

Sonuç

Bilerek eski Derleyiciler için kod yazıyoruz sürece, uygun olduğunda instancetype kullanmalısınız.

id döndüren bir mesaj yazmadan önce tereddüt gerekir. Kendinize sorun: bu sınıfın bir örneğini dönen bu? Eğer öyleyse, instancetype bir şey.

Kesinlikle id, dönüş için gereken durumlar vardır ama muhtemelen instancetype çok daha sık kullanacağız.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jordie Jordan

    Jordie Jorda

    27 Ocak 2008
  • sk8ingis4me

    sk8ingis4me

    16 Mart 2006
  • SoundHound

    SoundHound

    8 Mart 2006

İLGİLİ SORU / CEVAPLAR