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.
Related
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.
When writing an iOS app, where would I place a function that I intend to use from any other file?
For example, a function to convert a NSDate to a relative time string ("5 secs ago").
Would I make a class and make these functions all static?
Functions can be placed wherever convenient. If a function or group of functions is likely to be imported in many places, you can declare and implement them in their own .h/.m pair. So for example you might implement your date conversion function in a file named XYZDateUtilities.m, and declare it in XYZDateUtilities.h.
Declaring functions with the static qualifier would limit their scope to the file in which they were declared, so you wouldn't want to do that; in fact you'd want to do the opposite -- declare them as extern in the .h file so that they'll be visible in other files.
You have a couple options:
1) If you're extending the behavior of a class (such as the NSDate string conversion method you described), it may work best to simply create a category on said class.
Here's a tutorial on iOS categories:
http://mobile.tutsplus.com/tutorials/iphone/objective-c-categories/
Important Note:
Categories change a class's behavior (if you override a method) everywhere within the project whether or not you include the header (.h) file in another specific class's imports
For this reason, it's generally best to not override methods via a category, but instead, to create a subclass if you want to change certain methods.
For adding new methods, however, categories can be very convenient and useful.
2) If you want to create a new class that's imported everywhere, you can create said class and put its header import, i.e. #import "MyClass.h", into your project's prefix.pch file (found under the "supporting files" group within the project by default).
Anything that you put into the prefix.pch file will be available anywhere within your app. This is also a useful place to put constants (such as strings) or define enums that are used across many classes within the app.
I hope this helps. Let me know if further clarification is needed, and I'll do my best to help.
Cheers!
Another option would be to create a class for your helper methods and implement all the helpers as class methods.
e.g. HelperClass.h
+ (NSString *)getFrenchCapital
e.g. HelperClass.m
+ (NSString *)getFrenchCapital
{
return #"Paris";
}
Then import your helper class wherever you need it, and simply call the class methods:
e.g. Foo.m
#import "HelperClass.h"
...
- (void)logFrenchCapital
{
NSLog(#"Capital of France: %#", [HelperClass getFrenchCapital]);
}
If you make all functions static in a class, then alternative is to just define functions in .m file, and extern functions in .h file, just like what you do in C.
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.
I want to use a class I got from iosframeworks.com called UIImage+ProportionalFill. I know it's a category extending UIImage, but when I try to use one of its methods in another class I get a message saying no visible #interface for UIImage declares the selector 'nameOfWhateverMethodIWantToUse'. I'm not surprised to get an error, since there must be more to using it than dropping it into XCode, but how do I make the methods in the new category/class available to other classes?
You just need to import your category in the class you like to use it...
#import "UIImage+ProportionalFill.h"
I usually do this in the header file.
The compiler needs to be able to see the declaration of the methods, which should be in the category's header file. You must import the header file wherever you want to use the methods.
You need to #import the header containing the method declaration(s) in each file that uses said methods.
Note tha the methos should be prefixed; i.e. -JDnameOfWhateverMethodIWantToUse.
Note also that adding categories to framework classes willy nilly can easily lead to a rather awfully architected application that becomes difficult to refactor/maintain.
Based on what you said, I think you just forgot to import it.
#import "UIImage+ProportionalFill.h"
Write it on the top of the .h file of the class where you want to use the method.
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.