Private classes in Objective C - objective-c

I would like a pattern for a nested private class in Objective C.
Requirements are:
class will not be visible/accessible to other classes.
class can execute methods (i.e., not a C struct)
containing class members are visible/accessible to the nested class
Considering the comments, I am simplifying the requirements:
inner class may be accessible to other classes, but not visible (similar to using a category to hide private methods).
inner class does not have to be nested
Is it still not possible?

Objective-C has no notion of private classes or private instance variables in a formal declarative fashion.
Instead, visibility in Objective-C is entirely controlled by where you declare something. If it is in a header file, it can be imported by something else. If it is declared in an implementation file, it cannot (reasonably) be imported and, therefore, is effectively private to that compilation unit.
And by "it", I mean pretty much anything that can be declared; class, global, etc...
I.e. if you stick an #interface/#implementation pair for a class in a .m file, that class is effectively private to that compilation unit. Of course, without namespaces, make sure that class is uniquely named.
Consider this:
Foo.h:
#interface Foo: NSObject
... public interface
#end
Foo.m:
#interface __FooSupportClass: NSObject
... interface here ...
#end
#implementation __FooSupportClass
#end
#interface Foo()
#property(retain) __FooSupportClass *__fooSupport;
#end
#implementation Foo
#synthesize __fooSupport = fooSupport__;
... etc ...
#end
That gives you a private-by-visibility support class only available in your implementation with an instance variable and setter/getter methods on your class that are not visible outside the compilation unit either.
(Note that Objective-C has "instance variables", not "member variables". They are similar, but you'll be better off using the vocabulary of the language.)

Well you can have "semi-hidden" private methods. You can include an interface file that provides extension methods that is in the implementation file and then just implement the methods declared in there. I was curious about this before and asked a similar question.
Proper Objective-C Helper "Wannabe" Private methods?

Related

Class without superclass in Objective-C [duplicate]

This question already has answers here:
Defining an Objective-C Class without a base Class - Compiler Warning
(3 answers)
Closed 8 years ago.
Is it possible to create a class in Objective-C without a superclass.
If I create something like
#interface Samp
#end
I get the error message: "Class Samp defined without specifying a base class".
How come NSProxy compiles?
The pedantic answer is yes, you can. You just have to make your class a root class, which you can do by using the compiler attribute objc_root_class.
__attribute__((objc_root_class))
#interface Samp
#end
or using the convenience macro NS_ROOT_CLASS
NS_ROOT_CLASS
#interface Samp
#end
This is the same thing NSProxy does.
NS_ROOT_CLASS
#interface NSProxy <NSObject> {
Class isa;
}
Now, unless you're doing something really specific and out of the schemes, I don't see why you would want to do that.
Juts make your class to inherit from an existing root class, like NSObject (the most common) or NSProxy.
How come NSProxy compiles?
NSProxy class is special - it is one of Cocoa's two public root classes (NSObject is the other one). If you must define your own root class, this answer tells you how to do it. However, in practice there should be no reason to implement your own root class.

Is this a good practice to extract class extension into a separate header file for unit testing purposes in Objective-C?

Related to previous question about naming convention of class extensions:
In terms of API design, is this a good practice to extract class extension into a separate header file to provide private property access for unit tests?
// MyClass_Private.h
#interface MyClass()
#property (nonatomic, strong) NSString *myString;
#end
MyClass_Private indicate that this is a private class extension of MyClass. Is there any drawback of separating the class extension into a separate file? It fits perfectly with my needs, but I have never seen this in practice.
Update:
My question was theoretical, but to be concrete: I would like to mock some configuration value inside the implementation of MyClass. I would like to avoid passing these configuration values as parameters through the public interface because I would like to hide the class's implementation details.
For example to pass NSUserDefaults as parameters to every class under test seems a bit overcomplicated. That's why I decided to provide property access for unit tests through the class extension. Then I can mock NSUserDefaults used in class implementation that otherwise would come from the real user defaults.
Yes and no...
When unit testing, your aim is to prove that the unit correctly conforms to the interface it offers. You shouldn't need to know the internal details to do that. You can run tests passing a range of values to the unit and verify the response / result. If an interface is private then it is considered out of scope for the test.
You can run tests which include the private interface, that is a choice. From an implementation standpoint you can make the private interface publicly available to support this. If you aren't releasing a library and making the interface public then there is little cost to you (documentation of the purpose should suffice). An alternative is to keep the interface private and use the dynamic features of the language (runtime method lookup and invocation) to run the tests (be defining the private interface is a category in the test). The only disadvantage of that is that you won't learn that API changes in the class have broken the tests till you run them.
This is the difference between black box and white box testing. You need to decide which is appropriate for your situation and what level of interaction you want to allow.
Note that nothing is truly private. Using introspection and runtime lookup, your private methods are fully accessible...
With NSUserDefaults, your example makes sense as it's a dependency which should be replaced by a mock in unit tests. I discovered that I can do what you want to achieve in other way. Instead of keeping a separate header file with private property to be exposed to unit tests, I can define the property in the unit tests!
In MyClass.m:
#interface MyClass ()
#property(nonatomic, weak) NSUserDefaults* userDefaults;
#end
#implementation MyClass
#end
And then in unit tests you can also define a class extension for MyClass with userDefaults property. Then you can set the property to a mock object instead of the 'real' NSUserDefaults.
#interface MyClass ()
#property(nonatomic, weak) NSUserDefaults* userDefaults;
#end
#interface MyClassTest : XCTestCase
#property(nonatomic, strong) MyClass* testedObject;
#end
#implementation MyClassTest
- (void)setUp
{
[super setUp];
self.testedObject = [[MyClass alloc] init];
//I use OCMock in my example, of course any framework can be used
self.testedObject.userDefaults = OCMockObject mockForClass:[NSUserDefaults class]];
}
Of course it's not a perfect solution. Its advantage is that you don't have to split private interface of MyClass into two files. On the other hand, it's kind of a code duplication but the property is only duplicated in the test code, not the production code. It's a trade-off and you have to decide which approach is better for you.
I think that private methods should remain private: from the outside world you are testing that all available methods behave correctly. You don't have access to the private methods.
If your tests start failing on a public method, it will likely indicate a failure at the private level.
Test that a function returns a reversed string; don't test that charAtIndex() doesn't return an int - it isn't your current responcibility.

What does a variable defined as `Class<SomeProtocol> myClass` mean?

I am used to seeing things like id<NSCopying> myVar or MyObject<NSCopying> myVar, where we are stating that the variable in question can happily have NSCopying methods called on it without the compiler throwing a wobbly.
But I recently spotted some code that defined a variable like this:
Class<NSCopying> myClass;
I was wondering what this actually means as it seems subtly different from the top two examples. It seems like we're saying that the variable myClass can happily accept method calls from NSCopying - but having a class type able to accept these instance variable methods doesn't seem to make much sense.
It has occurred to me that variables of type class are technically objects themselves which is probably confusing me or the compiler (probably me!).
So I guess I'm asking:
What does something like Class<NSCopying> myClass; actually mean
How does Class<NSCopying> myClass; differ to something like id<NSCopying> myVar
Where could something like Class<NSCopying> myClass; be meaningfully used?
Notes:
I am just using NSCopying as an example and isn't integral to my use case
Wherever I refer to Class I mean the Obj-C keyword Class for declaring variables that are of type Class. I am not using this as a generic term for any class type.
Well I think it might mean that Class <NSCopying> myClass points to a class that implements NSCopying protocol. It can be useful if protocol has class method declarations and you want to call them.
For example:
#protocol NSSecureCoding <NSCoding>
#required
// The Secure Coding Guide should be consulted when writing methods that decode data.
+ (BOOL)supportsSecureCoding;
#end
id <NSCopying> myVar
Using id you can supply an instance of any type of class (so long as it implements the protocol, or you cast it to make the compiler trust you).
Class <NSCopying> myClass
Using Class means you can only supply a Class, not an instance.
Say you wanted your app to be configurable. Say you had a number of classes which offered a number of different features, but you didn't care about inheritance they had, just how to create and configure them. You could use a protocol that the class has to conform to and offer a method where the classes can be registered. Then you can instantiate those classes using the defined protocol without knowing anything else about the class.
Class<ProtocolName> is the type of a variable pointing to a class object with a meta class that conforms to ProtocolName. In other words: The class implements the methods from ProtocolName with class methods.
Example: NSCopying contains one required method:
#protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
#end
Class<NSCopying> means that there is a method
+ (id)copyWithZone:(NSZone *)zone;
in the class being pointed to. That is true for all NSObject derived classes and useful for using class objects as dictionary keys. See the documentation.

How should private and public members be implemented in objective-c?

I had some discussion related to the use of properties and instance variables at work, therefore I would like to find a wiki answer for that. Now, I know there's no real private member type in objective-c, everything is pretty much public. However, I'm a little bit concerned about the way we should design our classes and also to comply to OOP principles. I would like to hear opinions of these three design approaches:
A. According to various post and even to a new Stanford university iPhone development courses, you should always use properties everywhere you can. However IMHO, this approach brakes OOP design principles because in this case, all members become public. Why do I need to publish all my internal/local instance variables to outside? Also, there's some very little (but still) overhead if you use synthesized setters via properties, instead using local ivar directly. Here's a sample:
//==== header file =====//
#interface MyClass : NSObject
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#property (nonatomic, retain) NSString *propertyForPrivateMember;
#end
B. Another approach is to declare ivars in header file (without declaring relative properties) for private members, and in the same header file, to declare pure properties (without declaring relative ivars) for public members. In such case, ivars would be used directly in the class. This approach makes sense but not uses all benefits from properties because we have manually to release old values before setting the new ones. Here's a sample:
//==== header file =====//
#interface MyClass : NSObject{
NSString *_privateMember;
}
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#end
C. To declare pure properties (without declaring relative ivars) for public members in header file, and to declare pure properties (without declaring relative ivars) for private members in private interface in implementation file. This approach IMHO is more clear than the first one, but the same question remains: why do we have to have properties for internal/local members? Here's a sample:
//==== header file =====//
#interface MyClass : NSObject
#property (nonatomic, retain) NSString *publicMemberWithProperty;
#end
//==== implementation file =====//
#interface MyClass()
#property (nonatomic, retain) NSString *propertyForPrivateMember;
#end
This decision freedom annoys me a little bit and I would like to find a confirmation from respective sources about how things should be done. However, I was unable to find such strict statements in Apple docs on that, so please post a link to apple docs if any exists, or to any other theory that clears that.
By using class extensions you can have private properties.
A class extension syntax is simple:
Inside the .m-file, that has the class, create a unnamed category:
.h
#interface OverlayViewController : UIViewController <VSClickWheelViewDelegate>
- (IBAction)moreButtonClicked:(id)sender;
- (IBAction)cancelButtonClicked:(id)sender;
#end
.m
#import "OverlayViewController.h"
#interface OverlayViewController ()
#property(nonatomic) NSInteger amount;
#property(retain,nonatomic)NSArray *colors;
#end
#implementation OverlayViewController
#synthesize amount = amount_;
#synthesize colors = colors_;
//…
#end
Now you got all the aspects of properties for private members, without exposing them to public. There should be no overhead to synthesized properties to written getter/setters, as the compiler will create more or less the same at compile time.
Note that this code uses synthesized ivars. No ivar declaration in the header is needed.
There is a nice cocoawithlove article, about this approach.
You also ask why to use properties for private ivars. There are several good reasons:
properties take care for ownership and memory management.
at any point in future you can decide, to write a custom getter/setter. i.e. to reload a tableview, once a NSArray ivar was newly set. If you used properties consequently, no other changes are needed.
Key Value Coding support properties.
public readonly properties can be re-declared to private readwrite properties.
Since LLVM 3 it is also possible, to declare ivars in class extensions
#interface OverlayViewController (){
NSInteger amount;
NSArray *colors;
}
#end
or even at the implementation block
#implementation OverlayViewController{
NSInteger amount;
NSArray *colors;
}
//…
#end
see "WWDC2011: Session 322 - Objective-C Advancements in Depth" (~03:00)
There really is not a clean, safe, zero overhead, solution to this which is directly supported by the language. Many people are content with the current visibility features, while many feel they are lacking.
The runtime could (but does not) make this distinction with ivars and methods. First class support would be best, IMO. Until then, we have some abstraction idioms:
Option A
Is bad - everything's visible. I don't agree that it is a good approach, and that is not OOD (IMO). If everything is visible, then your class should either:
support all cases for how the client may use your class (usually unreasonable or undesirable)
or you provide them with a ton of rules via documentation (doc updates are likely to go unnoticed)
or the accessors should have no side effects (not OOD, and frequently translates to 'do not override accessors')
Option B
Has the deficiencies of Option A,, and like Option A, members may be accessed by key.
Option C
This is slightly safer. Like all the others, you can still use keyed access, and subclasses may override your accessors (even if unknowingly).
Option D
One approach to this is to write your class as a wrapper over over an implementation type. You can use an ObjC type or a C++ type for this. You may favor C++ where speed is important (it was mentioned in the OP).
A simple approach to this would take one of the forms:
// inner ObjC type
#class MONObjectImp;
#interface MONObject : NSObject
{
#private
MONObjectImp * imp;
}
#end
// Inner C++ type - Variant A
class MONObjectImp { ... };
#interface MONObject : NSObject
{
#private
MONObjectImp imp;
}
#end
// Inner C++ type - Variant B
class MONObjectImp;
#interface MONObject : NSObject
{
#private
MON::t_auto_pointer<MONObjectImp> imp;
}
#end
(Note: Since this was originally written, the ability to declare ivars in the #implementation block has been introduced. You should declare your C++ types there if it isn't necessary to support older toolchains or the 'fragile' 32-bit OS X ABI).
C++ Variant A is not as 'safe' as the others, because it requires the class' declaration visible to the client. In the other cases, you can declare and define the Imp class in the implementation file -- hiding it from clients.
Then you can expose the interface you choose. Of course, clients can still access your members if they really want to via the runtime. This would be easiest for them to do safely with the ObjC Imp type -- the objc runtime does not support C++ semantics for members, so clients would be asking for UB (IOW it's all POD to the runtime).
The runtime cost for the ObjC implementation is to write a new type, to create a new Imp instance for each instance, and a good amount of doubling of messaging.
The C++ type will cost practically nothing, apart from the allocation (Variant B).
Option E
Other approaches often dissociate ivars from interfaces. While this is a good thing, it's also very unusual for ObjC types. ObjC types/designs often maintain close relations to their ivars and accessors -- so you'll face resistance from some other devs.
Similarly to C++, Objective C provides public, private, and protected scopes. It also provides a package scope which is similar to package scope as defined in Java.
Public variables of classes can be references anywhere in the program.
Private variables can only be referenced within messages of the class that declares it. It could be used within messages that belong to ANY instance of the same class.
Package scope is similar to public scope within the same image, i.e. executable or library. According to Apple’s documentation, on 64-bit architectures, variables of package scope defined within a different image are to be treated as private.
Variable scope is defined by #public, #private, #protected, #package modifiers. These modifiers can be used both in a way similar to C++ or Java. All variables listed under a scope declaration belong to the same scope. Also, variables can be listed on the same line where the scope is declared.
#interface VariableScope : NSObject {
#public
int iVar0;
#protected
int iVar1;
#private
int iVar2;
#package
int iVar3;
#public int iVar01, iVar02;
#protected int iVar11, iVar12;
#private int iVar21, iVar22;
#package int iVar31, iVar32;
}
#end
For more info use the below link
http://cocoacast.com/?q=node/100

Minutia on Objective-C Categories and Extensions

I learned something new while trying to figure out why my readwrite property declared in a private Category wasn't generating a setter. It was because my Category was named:
// .m
#interface MyClass (private)
#property (readwrite, copy) NSArray* myProperty;
#end
Changing it to:
// .m
#interface MyClass ()
#property (readwrite, copy) NSArray* myProperty;
#end
and my setter is synthesized. I now know that Class Extension is not just another name for an anonymous Category. Leaving a Category unnamed causes it to morph into a different beast: one that now gives compile-time method implementation enforcement and allows you to add ivars. I now understand the general philosophies underlying each of these: Categories are generally used to add methods to any class at runtime, and Class Extensions are generally used to enforce private API implementation and add ivars. I accept this.
But there are trifles that confuse me. First, at a hight level: Why differentiate like this? These concepts seem like similar ideas that can't decide if they are the same, or different concepts. If they are the same, I would expect the exact same things to be possible using a Category with no name as is with a named Category (which they are not). If they are different, (which they are) I would expect a greater syntactical disparity between the two. It seems odd to say, "Oh, by the way, to implement a Class Extension, just write a Category, but leave out the name. It magically changes."
Second, on the topic of compile time enforcement: If you can't add properties in a named Category, why does doing so convince the compiler that you did just that? To clarify, I'll illustrate with my example. I can declare a readonly property in the header file:
// .h
#interface MyClass : NSObject
#property (readonly, copy) NSString* myString;
#end
Now, I want to head over to the implementation file and give myself private readwrite access to the property. If I do it correctly:
// .m
#interface MyClass ()
#property (readwrite, copy) NSString* myString;
#end
I get a warning when I don't synthesize, and when I do, I can set the property and everything is peachy. But, frustratingly, if I happen to be slightly misguided about the difference between Category and Class Extension and I try:
// .m
#interface MyClass (private)
#property (readwrite, copy) NSString* myString;
#end
The compiler is completely pacified into thinking that the property is readwrite. I get no warning, and not even the nice compile error "Object cannot be set - either readonly property or no setter found" upon setting myString that I would had I not declared the readwrite property in the Category. I just get the "Does not respond to selector" exception at runtime. If adding ivars and properties is not supported by (named) Categories, is it too much to ask that the compiler play by the same rules? Am I missing some grand design philosophy?
Class extensions were added in Objective-C 2.0 to solve two specific problems:
Allow an object to have a "private" interface that is checked by the compiler.
Allow publicly-readable, privately-writable properties.
Private Interface
Before Objective-C 2.0, if a developer wanted to have a set of methods in Objective-C, they often declared a "Private" category in the class's implementation file:
#interface MyClass (Private)
- (id)awesomePrivateMethod;
#end
However, these private methods were often mixed into the class's #implementation block (not a separate #implementation block for the Private category). And why not? These aren't really extensions to the class; they just make up for the lack of public/private restrictions in Objective-C categories.
The problem is that Objective-C compilers assume that methods declared in a category will be implemented elsewhere, so they don't check to make sure the methods are implemented. Thus, a developer could declare awesomePrivateMethod but fail to implement it, and the compiler wouldn't warn them of the problem. That is the problem you noticed: in a category, you can declare a property (or a method) but fail to get a warning if you never actually implement it -- that's because the compiler expects it to be implemented "somewhere" (most likely, in another compilation unit independent of this one).
Enter class extensions. Methods declared in a class extension are assumed to be implemented in the main #implementation block; if they're not, the compiler will issue a warning.
Publicly-Readable, Privately-Writeable Properties
It is often beneficial to implement an immutable data structure -- that is, one in which outside code can't use a setter to modify the object's state. However, it can still be nice to have a writable property for internal use. Class extensions allow that: in the public interface, a developer can declare a property to be read-only, but then declare it to be writable in the class extension. To outside code, the property will be read-only, but a setter can be used internally.
So Why Can't I Declare a Writable Property in a Category?
Categories cannot add instance variables. A setter often requires some sort of backing storage. It was decided that allowing a category to declare a property that likely required a backing store was A Bad Thing™. Hence, a category cannot declare a writable property.
They Look Similar, But Are Different
The confusion lies in the idea that a class extension is just an "unnamed category". The syntax is similar and implies this idea; I imagine it was just chosen because it was familiar to Objective-C programmers and, in some ways, class extensions are like categories. They are alike in that both features allow you to add methods (and properties) to an existing class, but they serve different purposes and thus allow different behaviors.
You're confused by the syntactic similarity. A class extension is not just an unnamed category. A class extension is a way to make part of your interface private and part public — both are treated as part of the class's interface declaration. Being part of the class's interface, an extension must be defined as part of the class.
A category, on the other hand, is a way of adding methods to an existing class at runtime. This could be, for example, in a separate bundle that is only loaded on Thursdays.
For most of Objective-C's history, it was impossible to add instance variables to a class at runtime, when categories are loaded. This has been worked around very recently in the new runtime, but the language still shows the scars of its fragile base classes. One of these is that the language doesn't support categories adding instance variables. You'll have to write out the getters and setters yourself, old-school style.
Instance variables in categories are somewhat tricky, too. Since they aren't necessarily present when the instance is created and the initializer may not know anything about them, initializing them is a problem that doesn't exist with normal instance variables.
You can add a property in a category, you just can't synthesize it. If you use a category, you will not get a compile warning because it expects the setter to be implemented in the category.
Just a little clarification about the REASON for the different behavior of unnamed categories (now known as Class Extensions) and normal (named) categories.
The thing is very simple. You can have MANY categories extending the same class, loaded at runtime, without the compiler and linker ever knowing. (consider the many beautiful extensions people wrote to NSObject, that add it functionality post-hoc).
Now Objective-C has no concept of NAME SPACE. Therefore, having iVars defined in a named category could create a symbol clash in runtime. If two different categories would be able to define the same
#interface myObject (extensionA) {
NSString *myPrivateName;
}
#end
#interface myObject (extensionB) {
NSString *myPrivateName;
}
#end
then at the very least, there will be memory overrun at runtime.
In contradiction, Class extensions have NO NAME, and thus there can be only ONE. That's why you can define iVars there. They are assured to be unique.
As for the compiler errors and warnings related to categories and class extensions + ivars and property definitions, I have to agree they are not so helpful, and I spent too much time trying to understand why things compile or not, and how they work (if they work) after they compile.