เมื่อประกาศวัตถุใน Cocoa ฉันควรตั้งค่าเป็นศูนย์หรือไม่

สมมติว่าฉันต้องการสร้างอินสแตนซ์ของ NSString ซึ่งเริ่มต้นเป็นค่าที่แน่นอน ขึ้นอยู่กับค่าของตัวแปรอื่น ปกติผมก็จะทำ

NSString *string;
if(foo == 1)
    string = @"Foo is one.";
else
    string = @"Foo is not one.";

อย่างไรก็ตาม ในโค้ดตัวอย่างบางส่วนที่ฉันเคยเห็น ฉันเคยเห็นผู้คนทำ

NSString *string = nil;
if(foo == 1)
    string = @"Foo is one.";
else
    string = @"Foo is not one.";

ความแตกต่างระหว่างทั้งสองคืออะไรและควรใช้วิธีใด?


person Jordan Kay    schedule 11.08.2009    source แหล่งที่มา


คำตอบ (4)


ความชอบส่วนตัวของฉันคือการเริ่มต้นตัวแปรใดๆ ทันที อย่างไรก็ตาม ในตัวอย่างที่คุณระบุ วิธีการทั้งสองนี้เทียบเท่ากัน

ใน C ภาษา (เช่น C, C++, Obj-C) ตัวแปรที่ไม่ได้เตรียมใช้งานทันทีอาจมีค่าขยะแบบสุ่ม การใช้ตัวแปรก่อนที่จะเตรียมใช้งานทำให้เกิดพฤติกรรมที่ไม่คาดคิด (ตั้งแต่หวังว่าจะขัดข้องไปจนถึงพฤติกรรมที่ไม่คาดคิด)

ตัวอย่าง ลองพิจารณาตัวอย่างต่อไปนี้:

int abs;
if (argument > 0) abs = argument;
else if (argument < 0) abs = -1 * argument;
NSLog(@"%i", abs);

ที่นี่โค้ดจะปล่อยให้ตัวแปร abs ไม่ได้รับการกำหนดค่าเริ่มต้นหาก argument เป็น 0 ดังนั้นคุณจะได้รับการบันทึกค่าสุ่มและจากนั้นนำไปสู่ความเสียหายต่อค่าในส่วนที่เหลือของโปรแกรม และเป็นการยากที่จะตรวจพบว่าปัญหาอยู่ที่ไหน!

หากคุณใช้การอ้างอิงที่ไม่ได้เตรียมใช้งาน คุณน่าจะได้รับ EXC_BAD_ACCESS

person notnoop    schedule 11.08.2009

การมอบหมายให้ nil อยู่ที่นั่นเพื่อไม่มีใครดูโค้ดและกังวลว่าตัวแปรจะอยู่ในสถานะที่ไม่ได้กำหนด

NSString *string;
NSLog(@"%p", string);

รหัสนั้นจะพิมพ์ค่าขยะเนื่องจากค่าของสตริงไม่ได้ถูกกำหนด

แทนที่จะเขียนโค้ดเหมือนในตัวอย่างของคุณ ฉันชอบใช้ตัวดำเนินการ ternary นี่คือตัวอย่าง:

NSString *string = (foo == 1) ? @"Foo is one." : @"Foo is not one.";

ตอนนี้ค่าของสตริงถูกกำหนดไว้เสมอ หากนิพจน์มีความซับซ้อนและบรรทัดยาว ให้ใช้ตัวแปรระดับกลาง

ทางออกที่ดีที่สุดสำหรับปัญหาต่างๆ ก็คือการกำจัดปัญหาออกไป แค่นี้ก็ทำได้แล้ว

person Jon Hess    schedule 11.08.2009

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

NSString *string = @"Foo is not one";
if(foo == 1)
    string = @"Foo is one.";

คอมไพเลอร์หลายตัวดีกว่าในการระบุค่าที่ไม่ได้เตรียมใช้งานในปัจจุบัน

เหตุผลประการหนึ่งของ Objective C ในการตั้งค่าตัวชี้เป็นศูนย์ (หลังการใช้งานครั้งล่าสุด) คือการรวบรวมขยะ

person Stephen Hoffman    schedule 11.08.2009

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

NSError *error = nil;
[SomeCocoaClass performOperationWithObject:obj error:&error];
if(nil != error){
//handle error
}

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

person Colin Wheeler    schedule 11.08.2009