2011-01-12 8 views
7

arasındaki davranış farkı Bir iPhone uygulamasında, UIView alt sınıfındaki tüm alt görünümleri kaldıran bir kod parçam var. Şun gibi görünüyor:UIView.subviews ve [NSView alt görünümleri]

NSArray* subViews = self.subviews; 
for(UIView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 

Bu iyi çalışıyor.

NSArray* subViews = [self subviews]; 
for(NSView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 

tamamen çalışmaz: Neredeyse (bir NSView alt sınıf itibaren) Bir Mac OS X uygulamasında aynı şeyi denedik kadar Aslında, gerçekten hem çok düşünmediler. Özellikle, zamanında, bu alın:

*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated. 

ben şöyle yapıyor sona erdi: gayet

NSArray* subViews = [[self subviews] copy]; 
for(NSView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 
[subViews release]; 

. Beni rahatsız eden şey, neden iPhone'da çalışıyor? kopya niteliği belirtildiğinde

@property(nonatomic,readonly,copy) NSArray *subviews; 

Benim ilk düşünce, belki @ synthesize'd getters bir kopyasını döndürür edildi:

subviews bir kopyası özelliktir. The doc, belirteçler için kopyanın semantiği konusunda nettir, ancak her iki şekilde de alıcılar için görünmüyor (veya en azından benim için belli değil). Ve aslında, kendi kendime bir kaç test yapıyorum, bu açıkça görülüyor. Hangisi iyi, sanırım bir kopyasını iade etmek birkaç sebepten dolayı sorunlu olurdu.

Soru şu: Yukarıdaki kod iPhone'da nasıl çalışıyor? NSView, gerçek bir alt görüntü dizisine açıkça bir işaretçi döndürüyor ve belki de UIView değil. Belki de sadece UIView'in bir uygulama detayıdır ve bu konuda çalışmadım.

Herhangi bir fikir sahibi olan var mı?

cevap

13

Bu, -[NSView subviews] numaralı hatadır. Kar Leopar için tamir edildiğine yemin edebilirdim, ama şimdi hiçbir kanıt bulamıyor.

Neyse ki, tüm subviews kaldırmak için daha basit bir yolu var:

[self setSubviews:[NSArray array]]; 
+3

Güçbelâ bir hata @ Mike bu. [SomeUIView alt görünümü] bu dizinin kopyasını döndürürken yalnızca [someNSView alt görüntülemeleri] alt görüntü dizisine işaretçi döndürür. Bu yüzden iOS'ta iyi çalışıyor. – jackal

2

Evet, Apple bunu nasıl uyguladı? Mac'te, alt görünümler görünüm tarafından kullanılan gerçek (değiştirilebilen) diziyi döndürür, bu nedenle görünüm eklerken veya çıkarırken hızlı numaralandırma özelliğini kullanamazsınız. ReverseObjectEnumerator kullanmak istiyorsanız, mümkün olabilir. Normal numaralayıcıyı kullanmayın çünkü kaldırılanları değiştirmek için alt görünümleri atlayabilir. Ancak iOS'ta Apple bu problemi fark etmiş ve bir kopyasını otomatik olarak iade ederek düzeltmiştir. Özellik beyanı sadece nasıl ayarlandığını açıklar, ancak elma da alıcı için kopyalamayı seçti. Kullanım

while([self.subviews count] > 0){ 
    [[self.subviews objectAtindex:0] removeFromSuperview]; 
} 

Umut bu yardım