Sınıf uzantısı ve sınıf kategorisi


82

Sınıf uzantıları @interface Class () çok daha güçlüdür ve değişkenleri sınıfa enjekte edebilir. Kategoriler @interface Class (Category)olamaz.

Başka ne gibi farklılıklar vardır ve bir sınıf uzantısı yerine bir kategori ne zaman kullanılmalıdır?


kategoriler gerçek kodlardır. bir sınıfa nasıl özellik eklediğinizdir. uzantılar (çok genel terimlerle) daha çok sözdizimsel şekerdir, gizlilikle ilgili belirli fikirleri diğer programcılara bildirmek için vb. uzantılar kod içermez ve kod değildir.
Şişko

Yanıtlar:


91

Temel fark, bir uzantı ile derleyicinin sizden ana yönteminizdeki yöntemleri uygulamanızı beklemesidir @implementation, oysa bir kategoride ayrı bir @implementationbloğunuz vardır. Bu nedenle, hemen hemen yalnızca ana .mdosyanızın en üstünde bir uzantı kullanmalısınız (bu arada, ivarlar için önemsemeniz gereken tek yer) - tam da bu, bir uzantı olması gerekiyor .


41
Bir uzantı, .mdosyanızda belirtmek istediğiniz özel yöntemler için en iyisidir . Bunu her zaman bunun için kullanıyorum. Yöntemlerinizi farklı bölümlerde - kategoriler :) - gruplamak istediğinizde veya kendi oluşturmadığınız mevcut sınıflara kod eklemek istediğinizde kategoriler daha kullanışlıdır .
jtbandes

1
Ayrıca, özellikleri kullanarak ek depolama alanı uzantıları ekleyebilirsiniz.
Paul.

23
Sınıf uzantıları ayrıca bir mülkün kamuya açık readonlyve özel olmasına izin vermek için özel olarak tasarlandı readwrite. Bunu kategorilerle yapamazsın (bilinçli bir tasarım seçimi).
bbum

Google, uzantı yerine özel yöntemleri uygulamak için neden kategoriyi kullanıyor? ör. code.google.com/p/gdata-objectivec-client/source/browse/trunk/…
Ryan,

uzantılar, @ uygulama bloğunda tüm yöntemlerin uygulanmasını gerektirir, ayrıca değişkenler için geliştirme sağlar. Ama temelde özel değişkenler kullanmak yerine bazı özel yöntemleri koymaya çalışıyoruz, bu nedenle bu durumda uzantı yerine kategoriyi tercih ediyoruz
Ankit Thakur 18'12

29

Bir sınıf uzantısı, bir kategoriye bir miktar benzerlik taşır, ancak yalnızca derleme zamanında kaynak koduna sahip olduğunuz bir sınıfa eklenebilir (sınıf, sınıf uzantısı ile aynı zamanda derlenir). Bir sınıf uzantısı tarafından bildirilen yöntemler, orijinal sınıf için @ uygulama bloğunda uygulanır; bu nedenle, örneğin, bir Cocoa veya Cocoa Touch sınıfı gibi NSString gibi bir çerçeve sınıfında bir sınıf uzantısı bildiremezsiniz.

Bir sınıf uzantısı bildirmek için sözdizimi bir kategorinin sözdizimine benzer ve şuna benzer:

@interface ClassName ()
@end

Parantez içinde isim verilmediğinden, sınıf uzantılarına genellikle anonim kategoriler denir.

Normal kategorilerin aksine, bir sınıf uzantısı kendi özelliklerini ve örnek değişkenlerini bir sınıfa ekleyebilir. Bir sınıf uzantısında aşağıdaki gibi bir özellik bildirirseniz:

@interface XYZAnimal () {
    id _someCustomInstanceVariable;
}
...
@end

IMHO, sınıf uzantılarını bir sınıfa özel arabirim olarak düşünmek en iyisidir. Birincil arabirim (.h dosyanızda), sınıfın diğer sınıflarla davranışsal sözleşmesini tanımlayan genel arabirim görevi görür.

Özel Bilgileri Gizlemek için sınıf uzantılarını kullanın

Sınıf uzantıları genellikle sınıfın kendisinin uygulanmasında kullanılmak üzere ek özel yöntemler veya özelliklerle ortak arabirimi genişletmek için kullanılır. Örneğin, bir özelliği arabirimde salt okunur olarak, ancak sınıfın dahili yöntemlerinin özellik değerini doğrudan değiştirebilmesi için uygulamanın üzerinde bildirilen bir sınıf uzantısında okuma yazma olarak tanımlamak yaygındır.

Örnek olarak, XYZPerson sınıfı, ABD'deki bir Sosyal Güvenlik Numarası gibi bilgileri izlemek için tasarlanmış, uniqueIdentifier adlı bir özellik ekleyebilir.

Gerçek dünyadaki bir kişiye atanmış benzersiz bir tanımlayıcıya sahip olmak genellikle büyük miktarda evrak gerektirir, bu nedenle XYZPerson sınıfı arabirimi bu özelliği salt okunur olarak ilan edebilir ve aşağıdaki gibi bir tanımlayıcı atanmasını isteyen bir yöntem sağlayabilir:

@interface XYZPerson : NSObject
    ...
    @property (readonly) NSString *uniqueIdentifier;
    - (void)assignUniqueIdentifier;
@end

XYZPerson sınıfının özelliği dahili olarak değiştirebilmesi için, özelliği, sınıfın uygulama dosyasının en üstünde tanımlanan bir sınıf uzantısında yeniden bildirmek mantıklıdır:

@property (readwrite) NSString *uniqueIdentifier;

Not: Readwrite niteliği isteğe bağlıdır çünkü varsayılan değerdir. Netlik açısından, bir mülkü yeniden beyan ederken bunu kullanmak isteyebilirsiniz.


7

Kategoriler, mevcut bir sınıfa yeni yöntemler eklemenize izin veren bir Objective-C dil özelliğidir. Uzantılar, ana uygulama bloğunda uygulanması gereken yöntemleri tanımlamanıza izin veren özel bir kategori durumudur.

Özel bildirimler, esas olarak bazı özellikler olan sınıf uzantılarında olabilir, çünkü onu çağırmadan önce bir yöntemi bildirmemize gerek yoktur.


"bu, ana uygulama bloğunda bildirilmelidir." -> ana uygulama bloğunda "uygulanmalıdır"
Fawkes

Teşekkürler, onu değiştirdim.
Julie Yu

0

ios uzantısı c # ile benzer, java soyut sınıfı veya
c # sınıfı uzantısına benzer arabirim ios kategorisi


Java, uzantı yöntemlerini desteklemez
Kullanıcı

afedersiniz ! Yazım hatasını kopyalayıp yapıştırın. ios kategorisi c # sınıfı uzantısına benzer.
Add080bbA

Hakkında bir örnek ekleyebilir misiniz?
Pedro Trujillo
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.