Re: Proper way to set up constants when building an iOS framework
Re: Proper way to set up constants when building an iOS framework
- Subject: Re: Proper way to set up constants when building an iOS framework
- From: Uli Kusterer <email@hidden>
- Date: Sat, 16 Apr 2016 13:19:07 +0200
On 12 Apr 2016, at 19:30, Alex Zavatone <email@hidden> wrote:
> On Apr 12, 2016, at 12:43 PM, Charles Jenkins wrote:
>
>> I imagine you’re already doing this, but your message wasn’t clear, so forgive me if I sound patronizing.
>>
>> The constants should be declared extern in the header file, but not assigned any values. The value assignments should appear inside a single .m file in your framework.
>
> I am not doing that. But it's what I'm going to be doing now.
>
> So, define them like this:
>
> SecurityDefaults.h
>
> extern NSString * const ABC_MY_IMPORTANT_CONSTANT;
NB - Just to save you some pain in the future, this is called a "declaration", not a definition. It is like a function or method prototype. It just tells the compiler "trust me, when it comes time to linking, there will be a variable with this name and type". The "definition" is what you then write in the .m file, and is the one, canonical definition of your constant.
Also, if this is a Cocoa project, I recommend you stick to the AppKit convention and use neither all-upercase nor the 'k' prefix, and instead just use inter-caps and your prefix. Like NSApplicationDidFinishLaunchingNotificationName. Less surprise for new people coming on the project that way.
Alex wrote:
> One thing though. I did do a #import of "Constants.h" into my framework's header file and that's not filling the role of what a .pch would fill in a standalone app, even though I thought that someone said it would.
A precompiled prefix header is a compile-time construct that only applies to the interior of your framework. You can't really tell people linking to your framework to add a certain prefix header. So you can use a pch for actually writing the framework implementation, but have to be careful to not require that someone has a certain PCH in the headers that you expose via your framework's headers folder (copied by the build phase). However, since clients usually #import your framework's umbrella header anyway, you could just put all important includes into the umbrella header (or headers included by your umbrella header) and then put your umbrella header into your framework's PCH. That way, you can write code without having to manually include stuff and any client gets the same combination of headers. If they want, they can then put the framework include into *their* PCH (i.e. usually the host app's).
That said, having everything in your prefix header invites people to add dependencies to their code across all module boundaries, so I would recommend manually including only the very headers the code in a particular location needs. It's a bit more typing, but it makes for more honest code, as modules who acquire too many includes are immediately visible and invite you to split them up or re-arrange them, that way restoring loose coupling and making your code more maintainable, and more reusable.
Alex wrote:
> If I put the #import there, the app immediately gets build errors.
>
> Am I missing something on where I should import the constants' header?
Do you have a "Copy Headers" build phase to copy your headers into the built product's package?
You may also want to read up on the C concept of "compilation units". Basically it means that (Objective)C(++) can only compile source files, not headers. So what it does is it goes through the list of sources in your project, compile each separately by taking a copy of it, replacing all #include and #import statements with the contents of the corresponding header file, and then taking that one huge source file and compiling it, making a note of all symbols it defines.
This means for one that including an ObjC header from a C file loses the information that this header was ObjC, as it all gets "pasted" into the .c file currently being compiled. So if your header gets included by a different language source file, you'll get all sorts of funny errors because the C compiler does not understand what '@interface' means etc. This could be one reason for the errors you're getting.
Charles wrote:
> Also, because of my C++ background, I’d see if the compiler would accept NSString const * const, because you want a constant pointer to an NSString that is constant; but I recognize that may not be the way things are done in Obj-C.
Yeah, while in general that would be true, there currently is no such thing as a NSString const as far as the ObjC compiler is concerned. ObjC's constants are still sort of a runtime construct ... in some ways, AFAIR.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://stacksmith.org
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden