ตัวชี้ไปยังวัตถุจะไปที่ nil
เมื่อนับเป็น 0 หรือเมื่อมีการเรียกการจัดสรรคืน ทำไมหรือทำไมไม่?
การจัดการหน่วยความจำใน Objective-C และการตั้งค่าตัวชี้เป็นศูนย์
คำตอบ (4)
ไม่ จะไม่ทำเช่นนั้น เนื่องจากการจัดสรรคืนไม่มีอำนาจในการเปลี่ยนตัวชี้ ทำได้เพียงคุณส่ง ตัวชี้ ไปยังตัวชี้เท่านั้น
หากคุณต้องการให้แน่ใจว่าตั้งค่าเป็นศูนย์ คุณต้องดำเนินการด้วยตัวเอง
บางคนคิดว่าแนวปฏิบัติที่ดีนี้ บางคนคิดว่ามันเสียเวลาเนื่องจากโค้ดของคุณควรมีโครงสร้างเพื่อไม่ให้ใช้พอยน์เตอร์หลังจากการจัดสรรคืน (จนกว่าจะมีการจัดสรรใหม่)
จริงๆ แล้วฉันโน้มตัวไปทางค่ายหลัง แต่ฉันเข้าใจได้ว่าทำไมผู้คนถึงต้องการปกป้องตัวเองจากการเข้าถึงหน่วยความจำที่ว่าง (การเขียนโปรแกรมเชิงป้องกันนั้นไม่ค่อยเป็นความคิดที่ไม่ดี)
nil
- person notnoop; 09.01.2010
__weak
พอยน์เตอร์จะเป็นศูนย์ในตัวเอง นอกจากนี้ การใช้มาโครในการทำเช่นนี้อาจทำให้เกิดข้อผิดพลาดได้ ดังที่ฉันกล่าวถึงในคำตอบด้านล่าง
- person Quinn Taylor; 09.01.2010
ภายใต้โมเดลหน่วยความจำแบบรีเทนต์แบบปกติ ไม่มี เมื่อเปิดใช้งานการรวบรวมขยะ สิ่งนี้จะเกิดขึ้นหากมีการประกาศตัวชี้เป็น __weak
(สำหรับออบเจ็กต์ Objective-C ค่าเริ่มต้นคือ __strong
) ตัวรวบรวมขยะจะลบการอ้างอิงที่อ่อนแอสำหรับคุณเมื่อถูกกำจัด ซึ่งทำให้เหมาะสำหรับการชี้ไปยังผู้รับมอบสิทธิ์และวัตถุกึ่งชั่วคราว ดูเพิ่มเติมที่ NSPointerArray, NSMapTable และ NSHashTable และการสนับสนุนความสัมพันธ์ที่อ่อนแอเช่นกัน (หมายเหตุ: เราต้องเข้าใจว่าการอ้างอิงที่คาดเดายากจะไม่ป้องกันไม่ให้วัตถุถูกรวบรวมขยะ แต่จะมีค่าเป็นศูนย์เมื่อไม่มีการอ้างอิงที่คาดเดายากชี้ไปยังที่อยู่เดียวกัน ดู เอกสารนี้ เพื่อสรุปโดยย่อเกี่ยวกับพฤติกรรมนี้)
การรวบรวมขยะ Objective-C ยังมีประโยชน์อื่นๆ อีกมากมาย และฉันขอแนะนำให้ใช้อย่างเต็มที่หากทำได้ (ใช้งานได้บน OS X 10.5+ แต่ไม่ใช่บน iPhone OS) การปรับปรุงประสิทธิภาพใน Snow Leopard นั้นน่าประทับใจที่สุด และมันก็ชั่วร้ายอย่างรวดเร็วตั้งแต่เริ่มต้น
ดังที่กล่าวไว้ @darren มีข้อดี: โดยปกติแล้ว แนวทางปฏิบัติที่ดีคือศูนย์ตัวแปรของคุณเองเมื่อเผยแพร่เนื้อหา หากคุณต้องการหลีกเลี่ยงการห้อยพอยน์เตอร์ไปยังอ็อบเจ็กต์ที่ปล่อยออกมามากเกินไป ทางออกที่ดีที่สุดของคุณคือปรับใช้นิสัยในการลบตัวแปรด้วยตัวเอง จะไม่มีค่าใช้จ่ายรันไทม์และสามารถอ่านได้ ที่สำคัญกว่านั้น การตั้งค่าตัวแปรเป็นศูนย์ช่วยให้ระบบรวบรวมขยะทำงานได้อย่างมีประสิทธิภาพสูงสุด เนื่องจากเป็นการบ่งชี้หน่วยความจำที่สามารถเรียกคืนได้อย่างปลอดภัย รหัสจะทำงานในทั้งสองโหมดได้อย่างสมบูรณ์แบบ
อย่างไรก็ตาม โดยทั่วไปฉัน ไม่ ไม่มีค่าใน -dealloc
เนื่องจากหน่วยความจำที่คุณกำลังแก้ไขกำลังจะถูกเรียกคืน และหากส่วนอื่น ๆ ของโค้ดอาจพบข้อผิดพลาดเนื่องจากการใช้ค่าที่เผยแพร่ พวกเขาไม่ควรใช้วัตถุที่จัดสรรคืนตั้งแต่แรก (สิ่งนี้มักเกิดขึ้นเมื่อวัตถุหนึ่งไม่ได้เก็บรักษาอีกวัตถุไว้อย่างถูกต้อง และวัตถุหลังถูกจัดสรรคืน เหลือ ตัวชี้ห้อย.) ข้อยกเว้นที่เป็นไปได้อาจรวมถึงการแยกส่วนแบบเป็นขั้น ซึ่งการอ้างอิงที่ไม่ใช่ศูนย์อาจทำให้เกิดปัญหาภายในการจัดสรรคืนเอง แต่ลักษณะการทำงานประเภทนี้โดยทั่วไปจะไม่ (และไม่ควร) เกิดขึ้นเมื่อทำลายวัตถุ
ฉันไม่แน่ใจว่าตัวชี้ไปที่ศูนย์หรือแค่ชี้ไปที่ข้อมูลที่ไม่ถูกต้อง แต่เป็นแบบแผนการเข้ารหัสที่ดีที่จะกำหนดตัวแปรของคุณให้เป็นศูนย์หลังจากที่คุณปล่อยมัน
ลองนึกถึงสถานการณ์นี้:
void *p = malloc (100);
while (someCondition)
{
// do something with p
}
free (p);
// p is not set to NULL for you, it still points to where it always did
ในทำนองเดียวกัน เมื่อมีการจัดสรรวัตถุ Objective-C ตัวชี้ไปยังวัตถุนั้นยังคงชี้ไปยังตำแหน่งที่วัตถุนั้นอยู่ สิ่งนี้ทำให้เกิดข้อผิดพลาดเมื่อมีการจัดสรรวัตถุอื่นลงในพื้นที่เดียวกัน (หรือแม้ว่าจะไม่มีการจัดสรรสิ่งใดลงในพื้นที่เดียวกันก็ตาม)