ฉันจะแปลง NSMutableArray เป็น NSArray ได้อย่างไร วัตถุประสงค์ -c?
NSArray *array = mutableArray;
ฉันจะแปลง NSMutableArray เป็น NSArray ได้อย่างไร วัตถุประสงค์ -c?
NSArray *array = mutableArray;
คำตอบ:
NSArray *array = [mutableArray copy];
Copy
ทำสำเนาไม่เปลี่ยนรูป สิ่งนี้มีประโยชน์มากเพราะ Apple สามารถเพิ่มประสิทธิภาพได้หลากหลาย ยกตัวอย่างเช่นการส่งเป็นแถวไม่เปลี่ยนรูปเท่านั้นยังคงมีวัตถุและผลตอบแทนcopy
self
หากคุณไม่ได้ใช้การรวบรวมขยะหรือ ARC จำไว้ว่า-copy
รักษาวัตถุ
copy
สร้าง NSArray ปกติไม่ใช่ NSMutableArray
NSArray
& NSMutableArray
, NSString
& NSMutableString
. แต่ไม่ใช่ตัวอย่างNSViewController
ที่มีสถานะที่เปลี่ยนแปลงได้เสมอ
An NSMutableArray
เป็น subclass ของNSArray
ดังนั้นคุณไม่จำเป็นต้องแปลงเสมอ แต่ถ้าคุณต้องการตรวจสอบให้แน่ใจว่าอาร์เรย์ไม่สามารถปรับเปลี่ยนได้คุณสามารถสร้างวิธีNSArray
ใดวิธีหนึ่งเหล่านี้ขึ้นอยู่กับว่าคุณต้องการให้มันทำงานอัตโนมัติหรือไม่:
/* Not autoreleased */
NSArray *array = [[NSArray alloc] initWithArray:mutableArray];
/* Autoreleased array */
NSArray *array = [NSArray arrayWithArray:mutableArray];
แก้ไข: วิธีการแก้ปัญหาโดย Georg Schöllyเป็นวิธีที่ดีกว่าในการทำและสะอาดกว่าโดยเฉพาะตอนนี้เรามี ARC และไม่ต้องโทรออกโดยอัตโนมัติ
ฉันชอบทั้งสองโซลูชั่นหลัก:
NSArray *array = [NSArray arrayWithArray:mutableArray];
หรือ
NSArray *array = [mutableArray copy];
ความแตกต่างหลักที่ฉันเห็นในพวกเขาคือวิธีการทำงานเมื่อ mutableArray เป็นศูนย์ :
NSMutableArray *mutableArray = nil;
NSArray *array = [NSArray arrayWithArray:mutableArray];
// array == @[] (empty array)
NSMutableArray *mutableArray = nil;
NSArray *array = [mutableArray copy];
// array == nil
[mutableArray copy]
สามารถทำให้ง่าย[nil copy]
ขึ้น ในวัตถุประสงค์ข้อความใด ๆ ที่ส่งไปยังศูนย์จะเป็นศูนย์เสมอ สิ่งสำคัญคือต้องจดจำความแตกต่างระหว่าง "ไม่มี" และ "อาเรย์ที่ไม่มีอะไรอยู่ในนั้น"
คุณลองใช้รหัสนี้ ---
NSMutableArray *myMutableArray = [myArray mutableCopy];
และ
NSArray *myArray = [myMutableArray copy];
ด้านล่างเป็นวิธีการแปลง NSMutableArray เป็น NSArray:
//oldArray is having NSMutableArray data-type.
//Using Init with Array method.
NSArray *newArray1 = [[NSArray alloc]initWithArray:oldArray];
//Make copy of array
NSArray *newArray2 = [oldArray copy];
//Make mutablecopy of array
NSArray *newArray3 = [oldArray mutableCopy];
//Directly stored NSMutableArray to NSArray.
NSArray *newArray4 = oldArray;
ในสวิฟท์ 3.0 มีใหม่ชนิดข้อมูลอาร์เรย์ อาร์เรย์ประกาศใช้let
คำหลักแล้วมันจะกลายเป็นNSArrayและถ้าประกาศใช้var
คำหลักแล้วก็กลายเป็นNSMutableArray
รหัสตัวอย่าง:
let newArray = oldArray as Array
ในวัตถุประสงค์ -c:
NSArray *myArray = [myMutableArray copy];
อย่างรวดเร็ว:
var arr = myMutableArray as NSArray
NSArray *array = mutableArray;
[mutableArray copy]
antipattern นี้เป็นรหัสตัวอย่าง หยุดการทำเช่นนั้นสำหรับอาร์เรย์ที่ไม่แน่นอนซึ่งเกิดขึ้นได้ซึ่งถูกส่งออกไปและถูกจัดสรรคืนเมื่อสิ้นสุดขอบเขตปัจจุบัน
ไม่มีวิธีที่ runtime สามารถปรับแต่งการคัดลอกอาเรย์ที่เปลี่ยนแปลงได้อย่างสิ้นเปลืองซึ่งกำลังจะออกจากขอบเขตลดลงเหลือ 0 และยกเลิกการจัดสรรให้ดี
NSMutableArray
ให้กับNSArray
ตัวแปรจะไม่แอบแฝงมัน (ซึ่งเป็นสิ่งที่คำถามของ OP เป็นเรื่องเกี่ยวกับ) การเปิดเผยค่าดังกล่าว (เช่นเป็นค่าส่งคืนหรือเป็นคุณสมบัติ) อาจส่งผลให้ยากต่อการดีบักปัญหาหากค่านั้นกลายพันธุ์โดยไม่คาดคิด สิ่งนี้ใช้กับการกลายพันธุ์ทั้งภายในและภายนอกเนื่องจากมีการแบ่งปันค่าที่ไม่แน่นอน
NSMutableArray
ตัวแปรก็เพียงพอแล้ว เนื่องจากวัตถุไม่เคยหยุดเป็นอาร์เรย์ที่ไม่แน่นอนการเรียกวิธีการกลายพันธุ์ในนั้นจะประสบความสำเร็จและกลายพันธุ์ข้อมูลที่ใช้ร่วมกัน หากในอีกทางหนึ่งอาเรย์ที่ไม่แน่นอนดั้งเดิมถูกคัดลอกเปลี่ยนเป็นอาเรย์ที่ไม่เปลี่ยนรูปและจากนั้นกำหนดให้กับNSMutableArray
ตัวแปรและมีวิธีการกลายพันธุ์ที่เรียกว่ามันการเรียกเหล่านั้นจะล้มเหลวโดยมีdoesNotRespondToSelector
ข้อผิดพลาดเนื่องจากวัตถุที่ได้รับการ ความจริงไม่เปลี่ยนรูปและไม่ตอบสนองต่อวิธีการเหล่านั้น
หากคุณสร้างอาเรย์ด้วยความผันแปรแล้วต้องการคืนค่าเวอร์ชันที่ไม่เปลี่ยนรูปคุณสามารถส่งคืนอาเรย์ที่ไม่แน่นอนในรูปของ "NSArray" ผ่านการรับมรดก
- (NSArray *)arrayOfStrings {
NSMutableArray *mutableArray = [NSMutableArray array];
mutableArray[0] = @"foo";
mutableArray[1] = @"bar";
return mutableArray;
}
หากคุณ "ไว้วางใจ" โทรไปรักษา (ในทางเทคนิคยังคงไม่แน่นอน) วัตถุกลับมาเป็นไม่เปลี่ยนรูป NSArray [mutableArray copy]
นี้เป็นตัวเลือกที่ราคาถูกกว่า
เพื่อตรวจสอบว่ามันสามารถเปลี่ยนวัตถุที่ได้รับผู้รับข้อความต้องขึ้นอยู่กับชนิดที่เป็นทางการของค่าตอบแทน หากได้รับตัวอย่างเช่นวัตถุอาร์เรย์พิมพ์เป็นไม่เปลี่ยนรูปมันไม่ควรพยายามที่จะเปลี่ยนแปลงมัน มันไม่ใช่วิธีการเขียนโปรแกรมที่ยอมรับได้เพื่อตรวจสอบว่าวัตถุนั้นเปลี่ยนแปลงได้หรือไม่ขึ้นอยู่กับความเป็นสมาชิกระดับของมัน
การปฏิบัติข้างต้นจะกล่าวถึงในรายละเอียดเพิ่มเติมที่นี่:
วิธีปฏิบัติที่ดีที่สุด: ส่งคืน mutableArray.copy หรือ mutableArray หากประเภทส่งคืนเป็น NSArray
ฉันค้นหาคำตอบใน swift 3 และคำถามนี้แสดงให้เห็นว่าเป็นผลลัพธ์ครั้งแรกในการค้นหาและฉันได้รับแรงบันดาลใจจากคำตอบดังนั้นนี่คือรหัส swift 3
let array: [String] = nsMutableArrayObject.copy() as! [String]
NSArray *array = [mutableArray copy];