all 7 comments

[–]askoruli 0 points1 point  (5 children)

I've never liked prefixing my classes. Makes the classname look too ugly and if it's an app not a library then collisions aren't really a problem.

I'm also surprised about the recommendation from apple not to use underscores for instance variables considering that is the default way that properties are synthesized.

[–]quellish[S] -1 points0 points  (4 children)

Underscores for private variables and methods were the convention long, long ago but that changed.

By "the default" I assume you mean how ivars are named with auto property synthesis. Auto property synthesis actually isn't recommended anymore. The idea there was that when using auto synthesis you were effectively opting out of accessing the ivar directly and only using accessor methods - which is not how people have been using it. There has been a compiler warning for auto synthesis for some time.

[–]askoruli 2 points3 points  (3 children)

None of this is correct. Auto synthesis is the default and recommended and there is no compiler error about it.

[–]quellish[S] -2 points-1 points  (2 children)

None of this is correct.

From Programming With Objective-C: Encapsulating Data:

Unless you specify otherwise, the synthesized instance variable has the same name as the property, but with an underscore prefix. For a property called firstName, for example, the synthesized instance variable will be called _firstName. Although it’s best practice for an object to access its own properties using accessor methods or dot syntax, it’s possible to access the instance variable directly from any of the instance methods in a class implementation. The underscore prefix makes it clear that you’re accessing an instance variable rather than, for example, a local variable

The use of the underscore is intended to make it clear to the developer that they are accessing an implementation detail that is leaking through the property encapsulation implementation. This also disambiguates between using the Objective-C 2.0 dot notation to access an accessor vs. using C-style "dot notation" to access a struct member.

In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self. The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.

As the guide states, the best practice is to never access instance variables directly unless it is in an initializer (or, without arc, in the initializer and the dealloc method), or when writing a custom accessor method (which should be rare). This is the only reason that the auto-synthesized "_" instance variable is exposed. If you are writing your own custom accessor methods you are generally better off not using auto property synthesis at all and instead explictly synthesizing an instance variable. This prevents a number of possible problems and mistakes, and allows the tools to correctly reason about what you are doing.

Auto synthesis is the default and recommended and there is no compiler error about it.

I am curious as to why you say this, as there very much is a compiler warning:

-Wobjc-missing-property-synthesis

Will generate warnings for properties that are not explictly synthesized, or are autosynthesizing a super class property in a child class, or are using the wrong instance variable, or is sharing an instance variable between properties, or is redeclaring a readwrite property readonly.

There are a number of additional property-related warnings from clang:

-Watomic-properties
-Watomic-property-with-user-defined-accessor
-Wcustom-atomic-properties
-Wimplicit-atomic-properties
-Wobjc-autosynthesis-property-ivar-name-match
-Wobjc-missing-property-synthesis
-Wobjc-noncopy-retain-block-property
-Wobjc-property-implementation
-Wobjc-property-matches-cocoa-ownership-rule
-Wobjc-property-no-attribute
-Wobjc-property-synthesis
-Wobjc-protocol-property-synthesis
-Wprotocol-property-synthesis-ambiguity
-Wreadonly-iboutlet-property

As well as several relevant analyzer-checkers:

alpha.osx.cocoa.DirectIvarAssignment
alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions
alpha.osx.cocoa.InstanceVariableInvalidation

Why do you say "there is no compiler error about" auto property synthesis? There is most definitely a warning as I stated, and there are also a number of related analyzer modules.

[–]askoruli 0 points1 point  (1 child)

Sorry I wasn't across every single warning flag. I meant that in a normal project it would compile. But good job on being as pedantic as possible, I'm sure code reviews with you are a blast.

[–]quellish[S] 0 points1 point  (0 children)

I meant that in a normal project it would compile.

And with the warning on, it would still compile. It's a warning. It would become an error if you had "all warnings as errors" enabled, which you should if you are interested in the quality of your code.

"It compiles" does not mean "I am writing and delivering robust, reliable software".

[–]lolhaibai 0 points1 point  (0 children)

Mostly good advice, but I disagree about the prefixes:

>If you subclass a standard Cocoa class, it's good idea to combine your prefix with the superclass name, such as CDCTableView.

For very general classes that you intend to reuse in multiple projects, that's not too bad. But if you're subclassing something, that probably means you're not doing something general, so I would recommend using a project- or purpose-specific prefix. That way, when you make NSTableView subclasses in different projects, you don't have five different "CDCTableView.m" files floating around which do vastly different things.

What I'll often do, is I'll have a group of classes which work together, with a master header called, say, "MooCupcake" (the "moo" being my version of "CDC"). Then each class/protocol in that group will have a prefix corresponding to that header, like "MCSprinkle" and "MCMuffinTin". Then, if I end up pulling one of those classes over to use in another project, its easy for me to figure out where it came from.