Defining name strings for NSNotification usage without coupling - cocoa

I'm going to be using NSNotifications in my app to decouple the code.
I want the compiler to help me when using strings as the names of the notifications, ie, if I mistype one, I want the compiler to tell me.
Using normal strings for this won't work, because the compiler won't know that if I typed "myNotificaion" that I really meant "myNotification".
One way to do this would be to use #defines, or const NSString variables, but that would mean they would have to be declared in a file, either the class they're originating from, or a globally included file.
The problem with having them declared in the class they originate from is that it will need to be included wherever the notifications are listened for, therefore creating a coupling that I don't want.
The problem with a global file is that it could possibly become long and messy and will contain lots of unrelated things.
Is there a way to accomplish this without this coupling or untidiness??

No, not as far as I'm aware, #defines and NSString constants is where it's at and you can't get around having to include these in whatever file requires access to the string.
You could create header files for the different parts of your app, so you might have JJDocumentNotifications.h and JJViewNotifications.h for example. You could then #import them into your precompiled header (.pch) file, so the file looks something like this:
#import <Cocoa/Cocoa.h>
#import "JJDocumentNotifications.h"
#import "JJViewNotifications.h"
That way, the headers will automatically be included in all the files in your target and you won't need to import them specifically.

Related

SASS partials: to be or not to be

Any soild reason I should prefer the sass partials over normal sass files (w/o leading underscore in the filename)?
I am not a full-time frontend developer and for now I use sass for simple organizing of my css - split styles into different files(modules/components), variables, functions, in-place calculations, mixins - I think that's all I do.
In general I create a single main sass files that combines all the files together like that:
// main.scss
#import 'vars'
#import 'funcs'
#import 'layout'
#import 'component/modal'
// etc.
And recently I noticed there is such thing as partials.
From the documentation I understand partials are independent files that are not exists on their own and are always a part of some other bigger modules.
By this logic it looks like vars.scss, funcs.scss are good candidates to be partials.
And what I can't understand is why _vars.scss is better than vars.scss.
The both variants will work well from the point of view of code splitting.
Possible reason is Compilation - the docs page says partials will not be compiled into separate css file. I can't agree that's a feature since it's fully under my control and depends only on how I configure the building tools I use. And anyway such sass internal things like variables/functions/mixins will never be translated directly to css - they only exist in the source code.
So I would like to understand maybe it's just a convention for visual separation internal files from others? You know there is a similar old practice of separation private/public members/variables in programming. Or maybe I just miss something?
Please advise what I can do with partials what I cannot do with normal files, are there any advantages of first ones?

Freemarker: difference between include and import?

I am trying to create two templates and use the variables of one .ftl (freemarker) file in another.
I don't really understand why I should use include vs import.
#include is very much like if you copy-paste the content of the included file into the place of the #include tag. #import also processes the target file, but doesn't output anything. Instead, it assigns the set of variables (the namespace) created by the imported template to the variables after the as keyword. As #macro-s and #function-s just create variables, #import is practical for pulling in a collection of utility macros and functions. Also note that #import-ing the same file for the second time does nothing (as the namespace is only populated once), while calling #include twice will process the target file twice.
As for JavaScript, FreeMarker runs on the server side, and the JavaScript runs in the browser. So the browser only ever sees the final output from FreeMarker.

Using precompiled headers in gcc

I am investigating using precompiled headers to reduce our compile times.
I have read the documentaiton on the subject here: https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html, where I read the following:
Only one precompiled header can be used in a particular compilation.
On the project whose build time I would like to improve, there are often very Long lists of includes. The above leads me to Think that to get the most performance improvements, I would have to make a collection of common includes, put them into a single Header file, compile and include that Header file.
On the other hand, I prefer to list my dependancies in particular file explicitly, so I would be inclined to include first the precompiled Header, followed by the Manual list of actual Header files.
I have two questions related to this:
Is my analysis and approach correct? Have I interpreted the statement correctly?
Doing this, I will use this file (say stdafx.h) in many places, thereby including files I don't need. I would like to explicitly list my dependencies however, for code documentation purposes.
Where I to do something like the following:
#ifdef USE_PRECOMPILED_HEADERS
#include "stdafx.h"
#else
#include "dep1.h"
#include "dep2.h"
#endif
I could periodically run a build without pre-compiled headers to check if all my dependencis are listed. This is a bit clunky however. Does anyone have a better solution?
If anyone has Information to help us obtain better results in our Investigation, I am happy to hear them.
Yes, your observation is absolutely fine!
You "would have to make a collection of common includes, put them into a single Header file, compile and include that Header file". This common header file is generally named as stdafx.h (although you can name it anything you want!)
I am afraid I don't really understand this part of the question.
EDIT :
Do you also want the standard headers (like iostream, map, vector, etc.) to be included as dependencies in the code documentation?
Generally this must be a NO. Hence, you must include only those header files in stdafx.h which are not under your control (i.e., [1] standard language includes [2] includes from dependent modules (mostly exposed interface headers)). Rest all includes (whose source is in the current project/module) must be explicitly included in each header file wherever required, and not put in the pre-compiled stdafx.h.
The above leads me to Think that to get the most Performance
improvements, I would have to make a collection of common
includes, put them into a single Header file, compile and
include that Header file.
Yes, this observation is correct: You put most (all?) includes in one single header file, which is then precompiled.
Which, in turn, means that...
any compilation without the aid of that header being precompiled will take ages;
you are relying on naming conventions or other means (documentation?) to make the information link between things referenced in your individual translation unit and their declaration.
I don't much like precompiled headers for those reasons...

How can you tell what namespace constants have been put in in swift?

In swift, a lot of cocoa and framework constants have been put into namespaces. For example, NSCompositeSourceOver is now NSCompositingOperation.CompositeSourceOver.
This is generally a good thing. However, sometimes it's hard to work out where Apple have put certain constants. For example, I currently need kCGDesktopWindowLevel, and I can't find the damn thing. (There is kCGDesktopWindowLevelKey, but that's not the same thing.)
Is there a reference for this, or some set of files I can grep?
In the original CGWindowLevel.h, kCGDesktopWindowLevel is a macro defined to CGWindowLevelForKey(kCGDesktopWindowLevelKey). The macro was not imported, but the latter works fine in Swift as long as you add some type conversions: Int(CGWindowLevelForKey(CGWindowLevelKey(kCGDesktopWindowLevelKey))). (You might wish to file a bug since these type conversions are required.) You can see some of these things by ⌘-clicking on the CGWindowLevelForKey function, or using :print_module CoreGraphics from swift -integrated-repl.

Best practice for Cocoa category naming conventions

I am tidying up my ancient Cocoa code to use modern naming conventions. There has been lots of discussion on best practices, but I'm unsure of one thing.
I'm thinking about adding a prefix to category method names, to ensure uniqueness. It seem generally agreed that this is a good idea, though most people probably don't bother.
My question is: what about a NSDictionary category method like -copyDeep that does a deep copy? The method used to be named -deepCopy, but I reversed the words as the analyzer looks for a prefix of "copy". Therefore I presumably couldn't add a prefix. And having the "prefix" in the middle or end of the method name seems messy and inconsistent.
I'd also be interested in thoughts on the style of prefix -- I currently use DS (for Dejal Systems) for class prefixes. But I know that Apple now wants to reserve all two-character prefixes for themselves, so am thinking about using Dejal, e.g. my class DSManagedObject would be renamed as DejalManagedObject. And getting back to categories, their methods would be renamed to add a dejal prefix, e.g. from -substringFromString: to -dejalSubstringFromString:. But -dejalCopyDeep would confuse the analyzer, so maybe I'd have to be inconsistent for such methods, and use -copyDeepDejal or -copyDeep_dejal?
I will be re-releasing my categories and various classes as open source once I've cleaned them up, so following the latest conventions will be beneficial.
I emailed the Apple Application Frameworks Evangelist about this, and got a reply that recommended not prefixing category method names. Which conflicts with the advice in the aforelinked WWDC10 session, but I assume reflects Apple's current thinking.
He recommended just looking at the beta seed API diffs to spot conflicts, which is what I've always been doing.
I agree with Kevin Ballard, you should prefix your category method names, particularly if you are going to distribute them to others. But you do have a valid concern the analyzer will be confused by DScopy. The ARC compiler will similarly be confused if the definition/implementation of DScopy is done without ARC and is used by another class using ARC (or vice versa).
My preferred solution is to use "ownership transfer annotations", such as:
NS_RETURNS_NOT_RETAINED
NS_RETURNS_RETAINED
They would be used to override the compilers default behavior of reading method names and acting on them. You might declare DScopy like so: (This declaration must be in a header file that is imported by all the classes that use this method mentioned due to link)
-(DSManagedObject *)DScopy; NS_RETURNS_RETAINED;
Source for NS_RETURNS... WWDC 2011 Session 322 - Objective-C Advancements in Depth. The meat of this issue begins at about time 9:10.
A note about "But I know that Apple now wants to reserve all two-character prefixes for themselves". As a personal preference I like to use the _ character to separate the prefix from the name, it works well for me. You might try something like:
-(DSManagedObject *)ds_copy; NS_RETURNS_RETAINED;
This would give you three characters, and arguably make the method name more readable.
Edit In response to link posted in comment.
However as Justin's answer to your original question says that can be broken.
With regards to attributes; I did not suggest using __attribute__((objc_method_family(copy))) I suggested using NS_RETURNS_RETAINED, which translates to :__attribute__((ns_returns_retained)). While the first example there won't even compile (as he says) using - (NSString *)string __attribute__((objc_method_family(copy))); it compiles with - (NSString *)string; NS_RETURNS_RETAINED; just fine.
Obviously also if the NS_RETURNS_.. are "hidden" from the compiler in separate the .ms or indirected in some other way and the compiler can't see the directives then it won't work. Because of this I would suggest putting the declaration for any methods that may cause the analyzer/compiler confusion in your main .h file (the one that imports all the others) to limit the chances that there will be an issue.

Resources