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
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 olarakid
tekrarlarını değiştirmek. Bu genellikleinit
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önmekinstancetype
değil mi dönüştürmek diğer yöntemler.Objective-C Kongreinstancetype
tüm yöntemler için açıkça yazmaktır.
- Vurgu benim. Kaynak: Adopting Modern Objective-C
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:
- Açık.Kodunuzu ne diyor, yerine başka bir şey yapıyor.
- Desen.Var olan fark etmez ne zaman iyi alışkanlıklar inşa ediyorsun.
- 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.
Nasıl bir uygulama android ADB araçlar...
Reset veya özel sürüm kullanmaya Gah i...
Nasıl bir karakter yerine Vim bir yeni...
Nasıl Krom XML yerine JSON dönmek için...
Nasıl twitter bootstrap menü hover yer...