ค่าคงที่ใน Objective-C


1002

ฉันกำลังพัฒนาแอปพลิเคชั่นCocoaและฉันใช้ค่าคงNSStringที่เป็นวิธีเก็บชื่อคีย์สำหรับค่ากำหนดของฉัน

ฉันเข้าใจว่านี่เป็นความคิดที่ดีเพราะช่วยให้เปลี่ยนคีย์ได้ง่ายหากจำเป็น
นอกจากนี้ยังเป็นแนวคิดทั้งหมดที่ 'แยกข้อมูลของคุณออกจากตรรกะของคุณ

อย่างไรก็ตามมีวิธีที่ดีในการกำหนดค่าคงที่เหล่านี้หนึ่งครั้งสำหรับการสมัครทั้งหมดหรือไม่?

ฉันแน่ใจว่ามีวิธีที่ง่ายและชาญฉลาด แต่ตอนนี้ชั้นเรียนของฉันเพิ่งกำหนดใหม่ที่พวกเขาใช้


7
OOP เกี่ยวกับการจัดกลุ่มข้อมูลของคุณด้วยตรรกะของคุณ สิ่งที่คุณเสนอคือการฝึกเขียนโปรแกรมที่ดีเช่นทำให้โปรแกรมของคุณเปลี่ยนได้ง่าย
Raffi Khatchadourian

คำตอบ:


1287

คุณควรสร้างไฟล์ส่วนหัวเช่น

// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

(คุณสามารถใช้externแทนFOUNDATION_EXPORTหากรหัสของคุณจะไม่ถูกใช้ในสภาพแวดล้อม C / C ++ แบบผสมหรือบนแพลตฟอร์มอื่น ๆ )

คุณสามารถรวมไฟล์นี้ในแต่ละไฟล์ที่ใช้ค่าคงที่หรือในส่วนหัวที่รวบรวมไว้ล่วงหน้าสำหรับโครงการ

คุณกำหนดค่าคงที่เหล่านี้ในไฟล์. m เช่น

// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

ควรเพิ่ม Constants.m ให้กับเป้าหมาย / เฟรมเวิร์กของแอปพลิเคชันของคุณเพื่อเชื่อมโยงกับผลิตภัณฑ์ขั้นสุดท้าย

ข้อดีของการใช้ค่าคงที่สตริงแทนที่จะ#defineเป็นค่าคงที่คือคุณสามารถทดสอบความเท่าเทียมกันโดยใช้การเปรียบเทียบตัวชี้ ( stringInstance == MyFirstConstant) ซึ่งเร็วกว่าการเปรียบเทียบสตริง ( [stringInstance isEqualToString:MyFirstConstant]) (และอ่านง่ายกว่า IMO)


67
สำหรับค่าคงที่จำนวนเต็มมันจะเป็น: extern int const MyFirstConstant = 1;
Dan Morgan

180
โดยรวมแล้วคำตอบที่ยอดเยี่ยมพร้อมด้วยข้อแม้ที่เด่นชัดหนึ่งข้อ: คุณไม่ต้องการทดสอบความเท่าเทียมกันของสตริงด้วยตัวดำเนินการ == ใน Objective-C เนื่องจากเป็นการทดสอบที่อยู่หน่วยความจำ ใช้ -isEqualToString เสมอ: เพื่อสิ่งนี้ คุณสามารถรับอินสแตนซ์อื่นได้อย่างง่ายดายโดยเปรียบเทียบ MyFirstConstant และ [NSString stringWithFormat: MyFirstConstant] อย่าตั้งสมมติฐานเกี่ยวกับอินสแตนซ์ของสตริงที่คุณมีแม้แต่กับตัวอักษร (ในกรณีใด ๆ #define คือ "preprocessor สั่ง" และถูกแทนที่ก่อนที่จะรวบรวมดังนั้นทางใดทางหนึ่งเรียบเรียงเห็นตัวอักษรสตริงในท้ายที่สุด.)
ควินน์เทย์เลอร์

74
ในกรณีนี้มันก็โอเคที่จะใช้ == เพื่อทดสอบความเท่าเทียมกับค่าคงที่ถ้ามันถูกใช้อย่างแท้จริงเป็นสัญลักษณ์คงที่ (เช่นสัญลักษณ์ MyFirstConstant แทนสตริงที่ใช้ @ "MyFirstConstant") สามารถใช้จำนวนเต็มแทนสตริงในกรณีนี้ (จริง ๆ แล้วนั่นคือสิ่งที่คุณกำลังทำ - ใช้ตัวชี้เป็นจำนวนเต็ม) แต่การใช้สตริงคงที่ทำให้การดีบักง่ายขึ้นเล็กน้อยเนื่องจากค่าของค่าคงที่มีความหมายที่มนุษย์อ่านได้ .
Barry Wark

17
+1 สำหรับ "Constants.m ควรเพิ่มไว้ในเป้าหมายของแอปพลิเคชัน / กรอบงานของคุณเพื่อให้เชื่อมโยงกับผลิตภัณฑ์ขั้นสุดท้าย" บันทึกสติของฉัน @amok ทำ "รับข้อมูล" บน Constants.m และเลือกแท็บ "เป้าหมาย" ตรวจสอบให้แน่ใจว่าได้ตรวจสอบเป้าหมายที่เกี่ยวข้องแล้ว
PEZ

73
@Barry: ในโกโก้ที่ฉันได้เห็นจำนวนของชั้นเรียนที่กำหนดของพวกเขาNSStringคุณสมบัติกับแทนcopy retainดังนั้นพวกเขาสามารถ (และควร) ถือตัวอย่างที่แตกต่างกันของNSString*ค่าคงที่ของคุณและการเปรียบเทียบที่อยู่หน่วยความจำโดยตรงจะล้มเหลว นอกจากนี้ฉันคิดว่าการใช้งานที่เหมาะสมอย่างสมเหตุสมผล-isEqualToString:จะตรวจสอบความเท่าเทียมกันของตัวชี้ก่อนที่จะเข้าสู่การเปรียบเทียบตัวละคร
Ben Mosher

280

วิธีที่ง่ายที่สุด:

// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"

วิธีที่ดีกว่า:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

ข้อดีอย่างหนึ่งของข้อที่สองคือการเปลี่ยนค่าของค่าคงที่ไม่ทำให้เกิดการสร้างโปรแกรมทั้งหมดขึ้นใหม่


12
ฉันคิดว่าคุณไม่ควรเปลี่ยนค่าของค่าคงที่
ruipacheco

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

7
มีการเพิ่มมูลค่าในการทำextern NSString const * const MyConstantคือทำให้ตัวชี้คงที่ไปยังวัตถุคงที่มากกว่าเพียงแค่ตัวชี้คงที่?
Hari Karam Singh

4
จะเกิดอะไรขึ้นถ้าฉันใช้การประกาศนี้ในไฟล์ส่วนหัวสแตติก NSString * const kNSStringConst = @ "ค่า const"; อะไรคือความแตกต่างระหว่างการไม่ประกาศและ init แยกต่างหากในไฟล์. h และ. m
karim

4
@Dogweather - ที่ที่ผู้รวบรวมเท่านั้นที่รู้คำตอบ IE หากคุณต้องการรวมไว้ในเมนูเกี่ยวกับคอมไพเลอร์ที่ใช้ในการรวบรวมบิลด์ของแอปพลิเคชันคุณสามารถวางไว้ที่นั่นได้เนื่องจากโค้ดที่คอมไพล์ไม่เช่นนั้นคงไม่รู้อยู่ดี ฉันไม่สามารถนึกถึงสถานที่อื่น ๆ ไม่ควรใช้มาโครในหลาย ๆ แห่งอย่างแน่นอน ถ้าฉันมี #define MY_CONST 5 และที่อื่น #define MY_CONST_2 25 ผลลัพธ์คือคุณอาจจบลงด้วยข้อผิดพลาดของคอมไพเลอร์เมื่อพยายามรวบรวม 5_2 อย่าใช้ #define สำหรับค่าคงที่ ใช้ const สำหรับค่าคงที่
ArtOfWarfare

190

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

ตัวอย่าง

// In your *.m file
static NSString * const kNSStringConst = @"const value";

เนื่องจากstaticคำหลัก const นี้จึงไม่สามารถมองเห็นได้นอกไฟล์


แก้ไขเล็ก ๆ น้อย ๆ โดย@QuinnTaylor :ตัวแปรคงที่จะมองเห็นได้ภายในหน่วยรวบรวม โดยปกติแล้วนี่เป็นไฟล์. m ไฟล์เดียว (ตามตัวอย่างนี้) แต่มันสามารถกัดคุณได้หากคุณประกาศในส่วนหัวซึ่งรวมอยู่ที่อื่นเนื่องจากคุณจะได้รับข้อผิดพลาด linker หลังจากการรวบรวม


41
แก้ไขไมเนอร์: ตัวแปรคงที่จะมองเห็นได้ภายในหน่วยรวบรวม โดยปกติแล้วนี่เป็นไฟล์. m ไฟล์เดียว (ตามตัวอย่างนี้) แต่มันสามารถกัดคุณได้หากคุณประกาศในส่วนหัวซึ่งรวมอยู่ที่อื่นเนื่องจากคุณจะได้รับข้อผิดพลาด linker หลังจากการรวบรวม
Quinn Taylor

หากฉันไม่ได้ใช้คำสำคัญคงที่ kNSStringConst จะสามารถใช้ได้ตลอดทั้งโครงการ?
Danyal Aytekin

2
ตกลงตรวจสอบแล้ว ... Xcode ไม่ได้มีการเติมข้อความอัตโนมัติในไฟล์อื่น ๆ หากคุณไม่ได้รับการป้อนข้อมูลแบบคงที่ แต่ฉันพยายามใส่ชื่อเดียวกันในสองที่ที่ต่างกันและสร้างข้อผิดพลาดของ linker ของ Quinn อีกครั้ง
Danyal Aytekin

1
คงที่ในไฟล์ส่วนหัวไม่ได้ให้ปัญหาลิงเกอร์ อย่างไรก็ตามแต่ละหน่วยรวบรวมรวมถึงไฟล์ส่วนหัวจะได้รับตัวแปรแบบคงที่ของตัวเองดังนั้นคุณจะได้รับ 100 หน่วยหากคุณรวมส่วนหัวจากไฟล์ 100 .m
gnasher729

@kompozer คุณวางไฟล์ส่วนไหนของไฟล์นี้ไว้?
Basil Bourque

117

คำตอบที่ยอมรับ (และถูกต้อง) ตอบว่า "คุณสามารถรวมไฟล์ [Constants.h] นี้ ... ในส่วนหัวที่รวบรวมไว้ล่วงหน้าสำหรับโครงการ"

ในฐานะที่เป็นสามเณรฉันมีความยากลำบากในการทำเช่นนี้โดยไม่มีคำอธิบายเพิ่มเติม - นี่เป็นวิธีที่: ในไฟล์ YourAppNameHere-Prefix.pch ของคุณ (ซึ่งเป็นชื่อเริ่มต้นสำหรับหัว precompiled ใน Xcode) นำเข้า Constants.h ของคุณภายใน#ifdef __OBJC__บล็อก

#ifdef __OBJC__
  #import <UIKit/UIKit.h>
  #import <Foundation/Foundation.h>
  #import "Constants.h"
#endif

นอกจากนี้โปรดทราบว่าไฟล์ Constants.h และ Constants.m ไม่ควรมีสิ่งใดอยู่ในนั้นอย่างแน่นอนยกเว้นสิ่งที่อธิบายไว้ในคำตอบที่ยอมรับ (ไม่มีส่วนต่อประสานหรือการนำไปใช้)


ฉันทำเช่นนี้ แต่มีบางไฟล์เกิดข้อผิดพลาดในการคอมไพล์ "การใช้ตัวระบุที่ไม่ได้ประกาศ 'CONSTANTSNAME' หากฉันรวมค่าคงที่ไว้ในไฟล์ที่ส่งข้อผิดพลาดมันทำงานได้ แต่นั่นไม่ใช่สิ่งที่ฉันต้องการ xcode และสร้างและยังคงมีปัญหา ... ความคิดใด ๆ
J3RM

50

โดยทั่วไปฉันใช้วิธีที่โพสต์โดย Barry Wark และ Rahul Gupta

แม้ว่าฉันไม่ชอบคำเดียวกันซ้ำทั้งในไฟล์. h และ. m โปรดทราบว่าในตัวอย่างต่อไปนี้บรรทัดเกือบจะเหมือนกันในไฟล์ทั้งสอง:

// file.h
extern NSString* const MyConst;

//file.m
NSString* const MyConst = @"Lorem ipsum";

ดังนั้นสิ่งที่ฉันชอบทำคือใช้เครื่องจักร preprocessor C ให้ฉันอธิบายผ่านตัวอย่าง

ฉันมีไฟล์ส่วนหัวซึ่งกำหนดมาโครSTR_CONST(name, value):

// StringConsts.h
#ifdef SYNTHESIZE_CONSTS
# define STR_CONST(name, value) NSString* const name = @ value
#else
# define STR_CONST(name, value) extern NSString* const name
#endif

คู่ใน. h / .m ของฉันที่ฉันต้องการกำหนดค่าคงที่ฉันทำสิ่งต่อไปนี้:

// myfile.h
#import <StringConsts.h>

STR_CONST(MyConst, "Lorem Ipsum");
STR_CONST(MyOtherConst, "Hello world");

// myfile.m
#define SYNTHESIZE_CONSTS
#import "myfile.h"

และ voila ฉันมีข้อมูลทั้งหมดเกี่ยวกับค่าคงที่ในไฟล์. h เท่านั้น


อืมมีข้อแม้เล็กน้อย แต่คุณไม่สามารถใช้เทคนิคนี้เช่นนี้หากไฟล์ส่วนหัวถูกนำเข้าสู่ส่วนหัวที่คอมไพล์แล้วเนื่องจากจะไม่โหลดไฟล์. h ลงในไฟล์. m เนื่องจากคอมไพล์แล้ว แม้ว่าจะมีวิธี - ดูคำตอบของฉัน (เนื่องจากฉันไม่สามารถใส่รหัสที่ดีในความคิดเห็นได้
Scott Little

ฉันทำงานนี้ไม่ได้ ถ้าฉันใส่ #define SYNTHESIZE_CONSTS ก่อน #import "myfile.h" มันจะทำ NSString * ... ทั้งใน. h และ. m (ตรวจสอบโดยใช้มุมมองผู้ช่วยและตัวประมวลผลล่วงหน้า) มันจะพ่นข้อผิดพลาดการกำหนดใหม่ ถ้าฉันใส่มันหลัง #import "myfile.h" มันจะ extern NSString * ... ในทั้งสองไฟล์ จากนั้นจะมีข้อผิดพลาด "สัญลักษณ์ที่ไม่ได้กำหนด"
arsenius

28

ฉันเองมีส่วนหัวที่อุทิศให้กับการประกาศ NSStrings คงที่ที่ใช้สำหรับค่ากำหนดดังนี้:

extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;

จากนั้นให้ประกาศพวกเขาในไฟล์. m ที่มาพร้อมกับ:

NSString * const PPRememberMusicList = @"Remember Music List";
NSString * const PPLoadMusicAtListLoad = @"Load music when loading list";
NSString * const PPAfterPlayingMusic = @"After playing music";
NSString * const PPGotoStartupAfterPlaying = @"Go to startup pos. after playing";

วิธีการนี้ให้บริการฉันดี

แก้ไข: โปรดทราบว่าวิธีนี้ใช้ได้ผลดีที่สุดหากใช้สตริงในหลายไฟล์ หากมีเพียงไฟล์เดียวเท่านั้นที่ใช้คุณสามารถทำได้#define kNSStringConstant @"Constant NSString"ในไฟล์. m ที่ใช้สตริง


25

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

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

คุณจะต้อง3ไฟล์.hไฟล์ที่มีคำจำกัดความคงที่.hไฟล์และ.mแฟ้มฉันจะใช้ConstantList.h, Constants.hและConstants.mตามลำดับ เนื้อหาของConstants.hเป็นเพียง:

// Constants.h
#define STR_CONST(name, value) extern NSString* const name
#include "ConstantList.h"

และConstants.mไฟล์ดูเหมือนว่า:

// Constants.m
#ifdef STR_CONST
    #undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"

ในที่สุดConstantList.hไฟล์มีการประกาศจริงในนั้นและนั่นคือทั้งหมด:

// ConstantList.h
STR_CONST(kMyConstant, "Value");

สองสิ่งที่ควรทราบ:

  1. ฉันต้องกำหนดแมโครใหม่ใน.mไฟล์หลังจาก #undefนำมาใช้เพื่อให้แมโครใช้

  2. ฉันยังต้องใช้#includeแทน#importเพื่อให้ทำงานได้อย่างถูกต้องและหลีกเลี่ยงการคอมไพเลอร์เห็นค่า precompiled ก่อนหน้านี้

  3. สิ่งนี้จะต้องมีการคอมไพล์ใหม่ของ PCH ของคุณ (และอาจเป็นโครงการทั้งหมด) เมื่อใดก็ตามที่มีการเปลี่ยนแปลงค่าใด ๆ ซึ่งไม่ได้เป็นกรณีที่มีการแยกออก (และทำซ้ำ) ตามปกติ

หวังว่าจะเป็นประโยชน์สำหรับใครบางคน


1
การใช้ #include แก้ไขอาการปวดหัวนี้ให้ฉัน
Ramsel

สิ่งนี้มีการสูญเสียประสิทธิภาพ / หน่วยความจำหรือไม่เมื่อเปรียบเทียบกับคำตอบที่ยอมรับ
Gyfis

ในการตอบสนองต่อประสิทธิภาพเมื่อเทียบกับคำตอบที่ยอมรับก็ไม่มี มันมีประสิทธิภาพสิ่งเดียวกันแน่นอนจากมุมมองของคอมไพเลอร์ คุณจะจบลงด้วยการประกาศเดียวกัน พวกเขาต้องการจะตรงเหมือนกันถ้าคุณแทนที่ข้างต้นด้วยextern FOUNDATION_EXPORT
Scott Little


12

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


11

หากคุณต้องการบางสิ่งบางอย่างเช่นค่าคงที่ทั่วโลก; วิธีที่รวดเร็วและสกปรกคือการประกาศค่าคงที่ลงในpchไฟล์


7
การแก้ไข. pch มักไม่ใช่ความคิดที่ดีที่สุด คุณจะต้องค้นหาสถานที่เพื่อกำหนดตัวแปรจริง ๆ แล้วเกือบจะเป็นไฟล์. m ดังนั้นจึงเป็นการดีกว่าที่จะประกาศในไฟล์. h ที่ตรงกัน คำตอบที่ได้รับการยอมรับในการสร้างคู่ค่าคงที่ / m เป็นคำตอบที่ดีถ้าคุณต้องการทั้งคู่ ฉันมักจะใส่ค่าคงที่ลงตามลำดับมากที่สุดเท่าที่จะเป็นไปได้โดยขึ้นอยู่กับว่าจะใช้ที่ใด
Quinn Taylor

8

ลองใช้วิธีการเรียน:

+(NSString*)theMainTitle
{
    return @"Hello World";
}

บางครั้งฉันก็ใช้มัน


6
วิธีการเรียนไม่คงที่ มีค่าใช้จ่ายในขณะดำเนินการและอาจไม่ส่งคืนออบเจ็กต์เดียวกันเสมอไป (หากคุณใช้งานในลักษณะนั้น แต่คุณไม่จำเป็นต้องใช้งานในลักษณะนั้น) ซึ่งหมายความว่าคุณต้องใช้isEqualToString:สำหรับการเปรียบเทียบซึ่งเป็น ค่าใช้จ่ายเพิ่มเติมในเวลาทำงาน เมื่อคุณต้องการให้ค่าคงที่
ปีเตอร์ Hosey

2
@Peter Hosey ในขณะที่ความคิดเห็นของคุณถูกต้องเราจะนำการแสดงนั้นมาหนึ่งครั้งต่อ LOC หรือมากกว่าในภาษา "ระดับสูง" อย่าง Ruby โดยที่ทุกคนไม่ต้องกังวล ฉันไม่ได้บอกว่าคุณไม่ถูกต้อง แต่เพียงแค่แสดงความคิดเห็นว่ามาตรฐานแตกต่างกันใน "โลก" ที่แตกต่างกันอย่างไร
Dan Rosenstark

1
จริงกับทับทิม รหัสประสิทธิภาพของคนส่วนใหญ่นั้นค่อนข้างไม่จำเป็นสำหรับแอปทั่วไป
Peter DeWeese

8

หากคุณชอบค่าคงที่เนมสเปซคุณสามารถใช้ประโยชน์จาก struct วันศุกร์ถาม & ตอบ 2011-08-19: ค่าคงที่และฟังก์ชัน Namespaced

// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
    NSString *didAddObject;
    NSString *didChangeObject;
    NSString *didRemoveObject;
} MANotifyingArrayNotifications;

// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
    .didAddObject = @"didAddObject",
    .didChangeObject = @"didChangeObject",
    .didRemoveObject = @"didRemoveObject"
};

1
สิ่งที่ยอดเยี่ยม! แต่ภายใต้ ARC คุณจะต้องนำหน้าตัวแปรทั้งหมดในการประกาศ struct ด้วย__unsafe_unretainedqualifier เพื่อให้มันทำงานได้
Cemen

7

ฉันใช้คลาสซิงเกิลเพื่อให้ฉันสามารถจำลองชั้นเรียนและเปลี่ยนค่าคงที่หากจำเป็นสำหรับการทดสอบ คลาสค่าคงที่มีลักษณะดังนี้:

#import <Foundation/Foundation.h>

@interface iCode_Framework : NSObject

@property (readonly, nonatomic) unsigned int iBufCapacity;
@property (readonly, nonatomic) unsigned int iPort;
@property (readonly, nonatomic) NSString * urlStr;

@end

#import "iCode_Framework.h"

static iCode_Framework * instance;

@implementation iCode_Framework

@dynamic iBufCapacity;
@dynamic iPort;
@dynamic urlStr;

- (unsigned int)iBufCapacity
{
    return 1024u;
};

- (unsigned int)iPort
{
    return 1978u;
};

- (NSString *)urlStr
{
    return @"localhost";
};

+ (void)initialize
{
    if (!instance) {
        instance = [[super allocWithZone:NULL] init];
    }
}

+ (id)allocWithZone:(NSZone * const)notUsed
{
    return instance;
}

@end

และมันถูกใช้แบบนี้ (สังเกตการใช้ชวเลขสำหรับค่าคงที่ c - มันจะบันทึกการพิมพ์[[Constants alloc] init]ทุกครั้ง):

#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"

static iCode_Framework * c; // Shorthand

@implementation iCode_FrameworkTests

+ (void)initialize
{
    c  = [[iCode_Framework alloc] init]; // Used like normal class; easy to mock!
}

- (void)testSingleton
{
    STAssertNotNil(c, nil);
    STAssertEqualObjects(c, [iCode_Framework alloc], nil);
    STAssertEquals(c.iBufCapacity, 1024u, nil);
}

@end

1

หากคุณต้องการเรียกสิ่งนี้NSString.newLine;จากวัตถุประสงค์ c และคุณต้องการให้มันคงที่คุณสามารถสร้างสิ่งนี้ได้อย่างรวดเร็ว:

public extension NSString {
    @objc public static let newLine = "\n"
}

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.