How do I know when do put my properties and methods in the .h file and when to put them in the .m interface? - objective-c

How do I know when do put my properties and messages in the .h file and when to put them in the .m interface?
I am thinking messages which are public like init should be in the .h file. What about properties which describe the class e.g. configuration type etc.

When you want to restrict access of any property, you can define that in .m file using class extension etc.
There is no as such rule defined for putting properties in .h or .m file, you need to check which properties you want to access outside the class(define those in .h) and which you do want to access outside(define in .m).

According to the Apple docs, one declares properties in "#interface" (.h) files. If you want to have private object only variables, those are called ivars and you wouldn't synthesize accessors to them.
Private properties (or "property redeclaration" in the docs) can be used in things like class extensions or protocols.

Related

Swift read private property from a .m file

I have a library that is written in Objective-C and using .m and .h files.
Is it possible for me to write an extension method for that class and get access to a private property that is only defined in the .m file and not defined in the .h file?
I have tried with the .valueForKey but I only get
payload_data_0
payload_data_1
payload_data_2
instance_type
which all are of type Builtin.RawPointer.
No. The only way for you to access it is to define it publicly in the header.
No, technically you can't. The documentation is very clear about this:
Extensions can add new computed properties, but they cannot add stored properties, or add property observers to existing properties.
If you need this for testing purpose, consider moving the private property declaration to a separate header file, like MyClass+Test.h , and have it added to the bridging header. But guess what, this makes those properties public anyways. Not a recommended solution.

How do .swift files keep the 'privacy' which the .h and .m files did in Obj-C

I have just started to shift from Obj-C to Swift in Xcode.
My question is about the new .swift files which replace the .h and .m files. The answers to this question partially tells me the differences, but I am still puzzled by the issue of 'privacy' with the new .swift file.
If I look up the definition of a class in Obj-C, I will be only be able to view the .h file (#interface) which contains the declaration of the class, its variables and methods. I cannot view the .m file (#implementation) which contains the code which controls how the class works (they are private which stops others from seeing/possibly plagiarising your code, I guess).
However, in Swift, it seems that something such as:
class NewClass: ParentClass {...}
creates a class in one go without the need for 2 sections - the #interface and #implementation. But when I look up the definition of a class (say, SKScene) in Swift, the code for the methods, etc, are still kept private somehow... How is this done?
The same situation in which you only see header files (e.g. a pre-compiled framework) will, with Swift, only make the interface available. The Swift files themselves will not be included in the framework. Instead, Xcode will generate pseudo-interface files that will be visible to users of the framework. You get property definitions and method signatures, but no implementations.

Why I can't access this property in class?

Please refer to this image, I have declared property matchResult, why couldn't I access it from its instance?
The other property "score" works, why?
The code runs in iOS6 environment.
Please open image in a new tab if you couldn't see it clearly.
Thanks
It seems that you have defined the property in the implementation file "CardMatchingGame.m",
using a class extension. That means that the property is only available in the #implementation block of this class.
To make the property accessible from other classes, move the declaration to the public #interface in "CardMatchingGame.h".
It is declared within the .m file and therefore not visible from "external". It does not matter that you access it from a method of the same class. You acces an external interface by referring to self.game.matchResult.
If game equals self then you could access self.matchResult. But I do not think it does because you fetch self.game from the array self.cardButtons.
So, you will either use self.matchResult if you are referring to self or you will have to move the property to the interface definition within the .m file.

How to define methods and properties only visible within an objective-c framework?

I am trying to write an objective-c framework and I would like to have methods and properties visible only within the framework. I know I could define them in a class extension inside the implementation file but then they will not be accessible by other classes.
One way I was thinking to do it was to define a category for example MyClass+Internals and make that header private. but make the MyClass.h header public. I was wondering if there was a better way of doing this. Also, I'm not sure you can define properties within a category I thought it was only methods. Thanks for any suggestions or feedback.
Say you have a class named "Foo", then in "Foo_Framework.h", create:
#interface Foo()
#property ....;
- .... method ....
#end
Then, make sure that "Foo_Framework.h" is imported before the #implementation Foo. That'll cause the class Foo to be compiled with the extended interface found in said header file. That header can then be used throughout your framework. Just don't make it available outside said framework.
You are correct that you can't declare properties (that are synthesized) in a category. That was one of the primary motivations for the creation of class extensions, of which the above is an example.

Private interface vs. private method - objective c

What is the difference between a private method and a private interface?
For example, I know that if you define a method in an implementation and its interface does not mention it, it is considered a private method. I have also seen things such as:
#interface Collector()
#property (readonly) NSMutableDictionary *count;
#end
Inside of the .m implementation file.
#interface Foo() creates a class extension (I stand corrected, props to bbum) on interface Foo which is like additional methods added to the interface. Some people also use #interafce Foo(Private) (category) instead of a class extension with (). It's more like "injecting" new methods into a class from outside the class.
Placing this in the .m file just keeps other things from "seeing it" in the .h file, but that's it. Basically people normally use categories or class extensions in .m files to specify private interfaces, but they are also used for things like UIKit uses categories to add row and section public methods to NSIndexPath. (This can be confusing.)
You don't really need to define private methods this way, but if you have a method called bar that calls method foo before foo is defined in the source file you'll get a compiler warning something like "object self may not respond to foo". You can get rid of that by defining foo before you define bar or any other foo-calling code. It's the same with plain C and functions.
Like Ole says this doesn't stop anyone from calling the private methods, it just declares your intention that they be private and causes the compiler to generate the "may not respond to" warnings even if they import the .h file.
EDIT
Also see http://www.friday.com/bbum/2009/09/11/class-extensions-explained/ for some explanation of categories vs. class extensions. Looks like class extensions should be more correct for defining private methods, from a compiler warning perspective, because category methods are optional. Wish my book would have explained this!
Objective-C has no totally private methods. The method declared in a private interface section in the .m file is invisible to outside callers but it is not private. If someone knows the method signature and ignores the compiler warning, they can call it from outside without problems.