Private property declaration in your class implementation? - iphone

Sorry if it's too obvious for you. I'm still learning objetive-c and proper design patterns.
Could you explain me why it is a good idea to declare a property inside #interface in implementation file of a class as a private property? You just can use a local declaration of your type with a class scope, since nobody outside your class would use any getter or setter for this property.
Thanks.

By using the property semantics, you get memory management behavior handled 'for free' by the compiler. Even if your data is private within your class, having the compiler emit correct release/retain/copy saves time and mistakes down the line.
With the modern ARC compiler, this is probably less of an issue now.

When you declare something as #private, usually an instance variable or a property, it became only accessible in methods of the class that declared it. Trying to access it from a subclass results in an error.
I know you didn't asked for this but there is also #protected, when a property is declared like this, it becomes only accessible in methods of the class that declared it and in the methods of any class that inherits from that class.
The source for this info is the best book I know about Objective-C - Learning Objective-C 2.0 by Robert Clair.

Related

Swift: Constant's internal implementation

In swift, how is constants implemented?
I read this article, which says
In Swift, constants are generally implemented as (inlined) function calls.
I am not clear of this statement.
Does Swift use a special approach to make constants?
Could anyone explain?
Are you familiar with "getter" and "setter" methods from other languages, such as Java? If a variable is made public in a language like Java, it's exposed to other classes to access directly. In the future, if this variable has to be changed, there's no way to do so without changing all of the other classes dependent upon. With getter/setter methods, dummy implementations can be made that don't do anything besides read/write the value. In the case that a change needs to be made, the implementation of these methods can be changed without effecting the public API of the class.
Swift implements variables with "properties", which are like a backing private variable with public getter/setter methods that are automatically generated. In the future, you can replace a property with a computer property with a special getter/setter implementation, without effecting the public API of the class, just like before. The difference here is that you don't need to write all of the default getters/setters yourself.

Why does adding 'dynamic' fix my bad access issues?

I'm having a strange issue that appeared with iOS 8 Beta 5 (this issue did not occur with previous versions).
I tried to create an empty project and try to replicate the issue, but I'm unable to do so, so I'm not quite sure where the issue lies.
What I'm seeing is that attempting to access methods of a custom NSManagedObject subclass results in a strange EXC_BAD_ACCESS error.
For example:
var titleWithComma: String {
return "\(self.title),"
}
This method, out of many others, causes this issue when called. However, adding a dynamic keyword before it makes the issue go away:
dynamic var titleWithComma: String {
return "\(self.title),"
}
I know I'm not giving enough info, because I honestly don't know how to pinpoint the actual issue, but can anyone explain what is possibly happening, and why adding dynamic might resolve this issue?
From Swift Language Reference (Language Reference > Declarations > Declaration Modifier)
Apply this modifier to any member of a class that can be represented
by Objective-C. When you mark a member declaration with the dynamic
modifier, access to that member is always dynamically dispatched using
the Objective-C runtime. Access to that member is never inlined or
devirtualized by the compiler.
Because declarations marked with the dynamic modifier are dispatched
using the Objective-C runtime, they’re implicitly marked with the objc
attribute.
It means that your property/method can be accessed by Objective-C code or class. Normally it happens when you sub-classing a Swift class of Objective-C base class.
This is from the prerelease Swift / Objective-C interoperability documentation:
Implementing Core Data Managed Object Subclasses
Core Data provides the underlying storage and implementation of properties in subclasses of the NSManagedObject class. Add the #NSManaged attribute before each property definition in your managed object subclass that corresponds to an attribute or relationship in your Core Data model. Like the #dynamic attribute in Objective-C, the #NSManaged attribute informs the Swift compiler that the storage and implementation of a property will be provided at runtime. However, unlike #dynamic, the #NSManaged attribute is available only for Core Data support.
So, because of some of the Objective-C runtime features that Core Data uses under the covers, Swift properties need to be specially annotated.

Adding methods to an Objective C class interface is optional?

Coming from a C++ background, one thing that confuses me about Objective C is the fact that you can add a method to a class without actually specifying it in the class interface. So I had a barrage of questions:
Why would someone choose to not add the method in the class interface?
Is it simply because of visibility?
Methods without a declaration in the interface are private?
Is declaring methods in a class interface just optional?
Is it different for overriding a base class' method?
The main difference is that C++ sets up much of its inheritance and types at compile time and Objective C does it mostly at runtime.
The only differences in putting a method in the interface (if all parameters are objects) in objective-C are that the compiler can see it at compile time and check that an object could respond to the method - if it does not then you get a warning but the compilation does succeed and the program will run and loo for the method at runtime. If the method is in the implementation of the class or a category (or some other way) then the run time will find it and call it successfully.
There are NO private methods you can call any method.
I believe that this is the only way to create private methods in Objective-C. The language does not support the ability to declare a private method so by not declaring a method in the header file you are making private from all callers.
Proper data encapsulation requires that you lock down access to members that either expose data or manipulates it. Not all members ought to be exposed.
Yes it is.
Yes, this is true.
Yes, this is true as well.
This I am not sure about - perhaps someone with more Objective-C knowledge could answer this one.
Extending Andrew Hare's answer to answer 5, no, it doesn't: whether declared in an #interface or otherwise, method replacement/refinement works the same.

Is it good style to declare methods in .h when they're intended to be overwritten by subclass?

I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.
But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).
Must I declare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?
Related: Is there a way to create an abstract class in Objective C?
Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:
Abstract Classes
Some classes are designed only or
primarily so that other classes can
inherit from them. These abstract
classes group methods and instance
variables that can be used by a number
of different subclasses into a common
definition. The abstract class is
typically incomplete by itself, but
contains useful code that reduces the
implementation burden of its
subclasses. (Because abstract classes
must have subclasses to be useful,
they’re sometimes also called abstract
superclasses.)
Unlike some other languages,
Objective-C does not have syntax to
mark classes as abstract, nor does it
prevent you from creating an instance
of an abstract class.
The NSObject class is the canonical
example of an abstract class in Cocoa.
You never use instances of the
NSObject class in an application—it
wouldn’t be good for anything; it
would be a generic object with the
ability to do nothing in particular.
The NSView class, on the other hand,
provides an example of an abstract
class instances of which you might
occasionally use directly.
Abstract classes often contain code
that helps define the structure of an
application. When you create
subclasses of these classes, instances
of your new classes fit effortlessly
into the application structure and
work automatically with other objects.
So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.
You can also use a protocol to force classes to implement certain methods.
However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.
Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.
You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.
#interface MyBaseClass : NSObject {
}
- (void)foo;
#end
#interface MyBaseClass(ProtectedMethods)
- (void)bar;
#end
#interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
#end
You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.
Your base class can log, assert, or throw when an abstract/pure-virtual method is called.
As other people have said, Objective-C does not support pure virtual classes.
You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:
- (void)iMustBeImplementedInaSubclass;
{
[self doesNotRecognizeSelector:_cmd]; // Pure virtual
}
As ben says you are probably better served by using a protocol to get your API design right.

#properties question on iPhone development

From what I've read, #properties and #synthesize are used to tell the compiler to to generate getters and setters for various properties of our class.
So I am confused when I see the source code of an Apple example, the GKTank, that uses only one class for the whole game (apart from the app delegate) and still most of the attributes of that class are defined in #property() and are synthesized, even if no other class will try to get/set them. What am I misunderstanding here?
Thanks
Using properties is generally good practice as the synthesized setters will do the right thing when it comes to memory management (retain, or simply assign, depending on how you've configured your property).
They are also a means of providing a clean separation between the public interface of your class and it's internal implementation.
This article offers some good advice on when and why to use properties and dot-notation.
It also allows you to use the dot syntax:
self.myProperty = something;
I don't know that particular example. However, it is considered good style to access members of the same class through accessors rather than referencing the members directly. By encapsulating the members as a property with getters and setters, the implementation details of the field may change while those details are abstracted by the getter/setter.
Furthermore, the declaration of properties on the class allows you to use the .-notation to access the properties so it might lead to more consistent code if you want to use that notation.