แม้ว่าคำถามนี้จะเก่า แต่สิ่งต่าง ๆ ไม่ได้เปลี่ยนไป แต่คำตอบที่ยอมรับนั้นไม่ถูกต้อง
enumerateObjectsUsingBlock
API ไม่ได้หมายถึงแทนที่for-in
แต่สำหรับกรณีการใช้งานที่แตกต่างกันโดยสิ้นเชิง:
- อนุญาตให้แอปพลิเคชันของตรรกะโดยพลการไม่ใช่ท้องถิ่น เช่นคุณไม่จำเป็นต้องรู้ว่าบล็อกทำอะไรเพื่อใช้กับอาร์เรย์
- การแจงนับพร้อมกันสำหรับคอลเลกชันขนาดใหญ่หรือการคำนวณหนัก (ใช้
withOptions:
พารามิเตอร์)
ได้อย่างรวดเร็วด้วยการแจงนับfor-in
ยังคงเป็นสำนวนวิธีการแจงคอลเลกชัน
การแจงนับอย่างรวดเร็วได้รับประโยชน์จากความกะทัดรัดของโค้ดความสามารถในการอ่านและการเพิ่มประสิทธิภาพเพิ่มเติมที่ทำให้รวดเร็วอย่างไม่เป็นธรรมชาติ เร็วกว่า C สำหรับวงเก่า!
การทดสอบอย่างรวดเร็วสรุปว่าในปี 2557 บน iOS 7 นั้นenumerateObjectsUsingBlock
จะช้ากว่าการใช้งาน 700% อย่างต่อเนื่อง
ประสิทธิภาพการทำงานเป็นเรื่องที่น่ากังวลจริงหรือไม่?
ไม่แน่นอนมีข้อยกเว้นที่หายาก
จุดคือการแสดงให้เห็นว่ามีผลประโยชน์เล็ก ๆ น้อย ๆ ที่จะใช้enumerateObjectsUsingBlock:
ในช่วงfor-in
ไม่มีเหตุผลที่ดีจริงๆ มันไม่ได้ทำให้โค้ดอ่านได้ง่ายขึ้น ... หรือเร็วกว่า ... หรือปลอดภัยต่อเธรด (ความเข้าใจผิดอื่นทั่วไป)
ตัวเลือกจะลงมาตามความชอบส่วนตัว สำหรับฉันตัวเลือกที่ใช้สำนวนและสามารถอ่านได้ชนะ for-in
ในกรณีนี้ที่มีการแจงนับจานโดยใช้
เกณฑ์มาตรฐาน:
NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
arr[i] = [NSString stringWithFormat:@"%d", i];
}
int i;
__block NSUInteger length;
i = 1000 * 1000;
uint64_t a1 = mach_absolute_time();
while (--i > 0) {
for (NSString *s in arr) {
length = s.length;
}
}
NSLog(@"For-in %llu", mach_absolute_time()-a1);
i = 1000 * 1000;
uint64_t b1 = mach_absolute_time();
while (--i > 0) {
[arr enumerateObjectsUsingBlock:^(NSString *s, NSUInteger idx, BOOL *stop) {
length = s.length;
}];
}
NSLog(@"Enum %llu", mach_absolute_time()-b1);
ผล:
2014-06-11 14:37:47.717 Test[57483:60b] For-in 1087754062
2014-06-11 14:37:55.492 Test[57483:60b] Enum 7775447746