iphone - ทดสอบว่ามีวัตถุอยู่หรือไม่

ฉันมีออบเจ็กต์หลายอย่างในแอปของฉันที่อาจกลายเป็นศูนย์ได้ในบางจุด และฉันมีวิธีการที่ในทางทฤษฎีใช้ในการทำให้ออบเจ็กต์เหล่านี้กลายเป็นศูนย์

แต่ถ้าฉันพยายามทำให้ไม่มีวัตถุที่ไม่มีอยู่ แอปก็จะหยุดทำงาน

ตัวอย่างเช่น...

[object1 release];
object1 = nil;

//... และหลังจากนั้น

[object1 removeFromSuperview]; // this will crash

แล้วฉันก็คิดว่าทำไมไม่ทดสอบเพื่อดูว่ามีวัตถุอยู่ก่อนที่จะลบออก...

if (object1 != nil)
 [object1 removeFromSuperview]; 
// this will crash too, because object1 cannot be tested for nil because it does not exist

ฉันจะตรวจสอบได้อย่างไรว่ามีวัตถุอยู่ก่อนทดสอบว่าไม่มีหรือไม่ บางสิ่งบางอย่างเช่น

if (object1 exists( {
  if(object1 != nil))
    [object1 removeFromSuperview)
}

เป็นไปได้ไหม?

ฉันเพิ่มสิ่งนี้เพื่อชี้แจง...

สิ่งที่ฉันหมายถึงคือ: ลองนึกภาพฉันมี object1 ประกาศบนส่วนหัวและเริ่มต้นในโค้ด ดังนั้นจึงมีอยู่และชี้ไปที่ข้อมูลอ้างอิงที่ถูกต้อง ณ จุดหนึ่ง วัตถุอาจถูกปล่อยออกมา ดังนั้นการอ้างอิงยังคงชี้ไปที่วัตถุแต่วัตถุนั้นถูกทำให้เป็นอิสระ แม้ว่าฉันจะทำให้วัตถุเป็นศูนย์หลังจากปล่อย ฉันก็ไม่สามารถทำอะไรกับมันได้

ปัญหาคือ: ฉันมีวิธีการบางอย่างที่ไม่ตรงกัน หนึ่งในนั้นจะสแกนหาวัตถุบางอย่างและนำออกหากพบ ฉันต้องตรวจสอบว่ามีวัตถุอยู่หรือไม่และการอ้างอิงชี้ไปยังวัตถุที่ถูกต้องก่อนปล่อยอีกครั้ง นี่คือประเด็น: ฉันจะทดสอบได้อย่างไรว่ามีออบเจ็กต์อยู่และการอ้างอิงของมันชี้ไปยังออบเจ็กต์ที่มีอยู่ที่ถูกต้องก่อนที่จะปล่อยมันอีกครั้ง เพื่อทำให้การปล่อยออบเจ็กต์ที่เผยแพร่แล้วเป็นโมฆะอีกครั้งและทำให้แอปเสียหาย


person Duck    schedule 07.04.2010    source แหล่งที่มา
comment
คุณหมายถึง object1 ทุกที่ที่คุณมี object หรือไม่? ฉันถือว่าเป็นเช่นนั้น   -  person itsmatt    schedule 07.04.2010
comment
ฉันได้ชี้แจงคำถามเดิมแล้ว ขอบคุณ.   -  person Duck    schedule 07.04.2010
comment
คุณกำลังผสมการใช้คำชี้ การอ้างอิง และอ็อบเจ็กต์เข้าด้วยกัน คำเหล่านี้มีความหมายที่แตกต่างกันมาก หากคุณไม่เข้าใจความแตกต่างระหว่างสิ่งเหล่านี้ จะช่วยให้คุณอ่านเกี่ยวกับการเขียนโปรแกรม C ได้ หากคุณเข้าใจพวกเขา มันจะช่วยผู้อ่านของคุณหากคุณระมัดระวังการใช้งานของคุณมากขึ้น โพสต์ของคุณอ่านยากนิดหน่อยด้วยเหตุนี้   -  person glorifiedHacker    schedule 07.04.2010


คำตอบ (3)


กล่าวโดยสรุป คำถามของคุณในการพิจารณาว่าตัวชี้ยังใช้งานได้อยู่นั้นกำลังไปในเส้นทางที่ผิด

หลังจากที่คุณปล่อยวัตถุ คุณต้องตั้งค่าเป็น null ทันที เพื่อที่คุณจะได้ไม่สามารถควบคุมวัตถุได้อีกต่อไป ถ้ามีสองวิธีเรียกใช้การเข้าถึงออบเจ็กต์เดียวกันแบบอะซิงโครนัส พวกเขาจะต้องซิงโครไนซ์ที่จุดนั้นเพื่อให้การปล่อยและการตั้งค่าเป็น null เกิดขึ้นพร้อมกันในหนึ่งเธรดก่อนที่อีกวิธีหนึ่งจะมีโอกาสขัดจังหวะ

person Ed Marty    schedule 07.04.2010

คุณแค่คาดเดาหรือคุณได้ลองสิ่งนี้จริง ๆ แล้ว? เพราะในภาษาการเขียนโปรแกรมอื่นๆ การเรียกใช้เมธอดเป็น nil จะทำให้เกิดความผิดพลาด ใน Objective-C สิ่งนี้ไม่เป็นความจริง ใน Objective-C คุณสามารถส่งข้อความถึงศูนย์ได้โดยไม่ทำให้เกิดความผิดพลาด ข้อความเหล่านี้ก็ไม่มีผลใดๆ

ในความเป็นจริง คุณสามารถลามกอนาจารจริงๆ และทำสิ่งต่อไปนี้ได้โดยไม่ผิดพลาด:

[(id)nil setTitle:@"Testing"];  // This will not cause a crash

หากแอปของคุณขัดข้อง นั่นไม่ใช่เพราะว่าคุณไม่ได้ส่งข้อความเลย อย่างไรก็ตาม อาจเป็นไปได้ว่าคุณไม่สามารถตั้งค่าตัวชี้เป็นศูนย์ได้ และคุณกำลังส่งข้อความถึงวัตถุในหน่วยความจำที่คุณไม่ได้เป็นเจ้าของ จากรายละเอียดที่คุณให้ไว้ในการอัปเดต กล่าวคือ คุณมีเธรดแบบอะซิงโครนัสที่เข้าถึงออบเจ็กต์เหล่านี้ ฉันคิดว่ามีความเป็นไปได้มากที่คุณกำลังส่งข้อความไปยังพอยน์เตอร์ซึ่งมีออบเจ็กต์ถูกเผยแพร่แล้ว แต่ยังไม่ได้ตั้งค่าเป็นศูนย์

person glorifiedHacker    schedule 07.04.2010
comment
ขอบคุณ. ฉันไม่ได้คาดเดา ปัญหาที่ฉันเห็นตอนนี้ไม่ใช่การทดสอบกับศูนย์คือการทดสอบความถูกต้องของข้อมูลอ้างอิงก่อนทำการทดสอบ ลองนึกภาพการอ้างอิงที่ชี้ไปยังมุมมองที่ได้รับการปลดปล่อย การอ้างอิงนั้นถูกต้อง แต่วัตถุที่อ้างอิงนั้นไม่ถูกต้องเช่นกัน - person Duck; 08.04.2010

ฉันเคยเปรียบเทียบวัตถุกับศูนย์มาก่อนโดยไม่มีปัญหาใดๆ

person Lee Probert    schedule 07.04.2010
comment
ขอบคุณ. ปัญหาที่ฉันเห็นตอนนี้ไม่ใช่การทดสอบกับศูนย์คือการทดสอบความถูกต้องของข้อมูลอ้างอิงก่อนทำการทดสอบ ลองนึกภาพการอ้างอิงที่ชี้ไปยังมุมมองที่ได้รับการปลดปล่อย การอ้างอิงนั้นถูกต้อง แต่วัตถุที่อ้างอิงนั้นไม่ถูกต้องเช่นกัน อย่างไรก็ตามขอบคุณสำหรับคำตอบของคุณ +1 สำหรับความพยายามในการช่วยเหลือ :-) - person Duck; 08.04.2010