2010-02-27 20 views
26

appendData yöntemini kullanarak bir NSMutableData örneğine kolayca bayt ekleyebilirim, ancak verileri kaldırmak için benzer bir yöntem görmüyorum? Bir şeye bakıyor muyum yoksa yeni bir nesne oluşturmam ve sadece ihtiyacım olan baytları kopyalamam mı gerekiyor? NSMutableData yanaNSMutableData baytları nasıl kaldırır?

cevap

71

aşağıdaki yöntemin belgelerine bakınız

aralığının uzunluğu replacementLength eşit değilse, alıcı yeniden boyutlandırılır olduğunu yeni baytları barındırır. numaralı alıcıdaki herhangi bir bayt geçmiş aralığı, yeni bayt sayısına uyacak şekilde kaydırılır. Bu nedenle replacementBytes için NULL ve replacementLength için 0 değerini aralığında aralıktaki alıcıyı silmek için geçirebilirsiniz. Bu da ( sıfır uzunlukta olabilir) ekleme etkiye sahip aralığı uzunluğu daha byte (veya “bir yerine görür, ve daha”) bir dizi yerini alabilir.

kullanın ucundan 10 byte kaldırmak için:

[data setLength:[data length] - 10]; 

Ayrıca replaceBytesInRange aracılığıyla yapılabilir, ancak bayt gerçekten kaldırılmaz, çünkü aslında çok hızlıdır. Bunun yerine, yalnızca iç boyut değişkeni değiştirilir ve NSMutableData, baytlar kaldırılmış gibi davranır. IOW, bu bir O (1) işlemidir (bu, kaç bayttan bağımsız olarak, her zaman gerçekleştirmek için eşit uzun süre alacağı anlamına gelir) ve çok hızlıdır.

önden 10 bayt kaldırmak için kullanımı:

[data replaceBytesInRange:NSMakeRange(0, 10) withBytes:NULL length:0]; 

orta (örn sonra 20 bayt), kullanım içinde, 10 bayt kaldırmak için:

[data replaceBytesInRange:NSMakeRange(20, 10) withBytes:NULL length:0]; 

replaceBytesInRange, bir O (n) operasyonu olsa da. Bu, 100 bayt'ın kaldırılması ne kadar sürecek olursa olsun, 200 baytlık kaldırmak için iki kat daha uzun sürecek anlamına gelir. Hala oldukça hızlı ve sadece bilgisayarınızın belleği (RAM) ile sınırlı. 10 MB veriye sahipseniz ve önden 1 MB çıkarırsanız, kaldırılan MB'nin boşluğunu doldurmak için 9 MB kopyalanır. Dolayısıyla işlemin hızı, sisteminizin 9 MB RAM'i bir adresten diğerine ne kadar hızlı taşıyabileceğine bağlıdır.Ve bu yüzlerce MB içeren NSMutableData nesneleriyle uğraşmadıkça, yeterince hızlıdır.

+0

Bu, daha az upvotes ve şimdi alakasız olan bir cevabı türevi olmasına rağmen, bu harika bir cevaptır. Bunu bağımsız bir cevap yapmak için gözden geçirebilir misiniz? +1 –

+1

@Yar: Elbette, neden olmasın. Referansı diğer cevabı kaldırdım. – Mecki

+0

Bir şekilde bugün bu cevaba geri döndüm, "Aralığını da ekleyebildiğiniz aralığın uzunluğundan daha fazla baytla (sıfır uzunluktaki) bir aralığı da değiştirebilirsiniz. daha fazla ekle ”. Teğetsel ama ilgili. Teşekkürler! –

3

sen CFDataDeleteBytes kullanabilirsiniz, ücretsiz CFMutableDataRef ile köprülü() fonksiyonu: Kaldırmak istediğiniz veri sonunda ise

NSMutableData *data = ... 
CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4)); 
+3

Dikkatli olun. Bu yol aşağı performans sıkıntıları yatıyor. Göreceli olarak az sayıda düzenleme yapıyorsanız veya küçük bir veriyle çalışıyorsanız büyük bir sorun olmaz. Daha büyük veya sık veya performansa duyarlı herhangi bir şey, bir türün optimize edilmiş veri yapısını kullanmayı düşünün. – bbum

+0

Teşekkürler, bu harika çalıştı. NSMutable verilerin CFMutableDataRef ile “ücretsiz köprülenmiş” olduğunu nereden biliyorsunuz? NSMutableData belgelerinde bundan hiç bahsetmiyorum? – Kyle

+0

Eğer NSMutableData docs "Genel Bakış" bölümünde http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSMutableData_Class/Reference/NSMutableData.html bakarsanız görürsünüz İkinci paragrafta belirtilen –

1

, sen

[NSMutableDataInstance setLength:[NSMutableDataInstance length] - n]; kullanabilirsiniz

veya obj-c 2.0 sözdizimi ile

NSMutableDataInstance.length -= n; 

Bundan daha karmaşık bir şey için ham verileri manipüle etmenizi tavsiye ederim. Aşağıdaki

- (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)replacementBytes length:(NSUInteger)replacementLength 

Elma açıkça söylüyor:

+0

Bahşiş için teşekkürler! Ancak önünden kaldırmaya çalışıyorum :) – Kyle

0

bu parçacığı cevabı var olduğunu görüyoruz, ama yine de bu değerli eklenti olabilir. NSMuttableData tüm bayt kaldırmak için, yeni veri oluşturmak ve orijinal kopyalayabilirsiniz:

[myData setData:[NSData dataWithBytes:NULL length:0]]; 

Bu iyi çalışıyor.

İlgili konular