I am reading this document to learn objective-C: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW1
I the topic "Use Class Extensions to Hide Private Information" (page 73 of pdf) it says:
Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class itself. It’s common, for example, to define a property as readonly in the interface, but as readwrite in a class extension declared above the implementation, in order that the internal methods of the class can change the property value directly.
What i dont understand in this statement is that since we can change the readonly property from within any private method defined in class extension without that property being re-declared as readwrite in class extension, what does it achieve by re-declaration of that property as readwrite?
You can always change the property through its instance variable (_ivar = ...), but you won't be able to change it using the dot-property syntax (self.myProp =...) unless you redeclare it as readwrite. You will also need to provide additional information like whether the property is strong or weak in this case.
Actually my assumption that "we can change the readonly property from within any private method defined in class extension" is wrong. Class extension cannot use instance variables synthesized automatically for a given readonly property, because they are private (NOT protected) by default.
Even though the document i mention says that instance variable automatically synthesized for a given property has a leading underscore (_Make) in front of it. It actually is not true ( at least not in Xcode 4.6.3 ). It bears the same name has the property itself (unless you synthesize the instance variable itself #synthesize Make = _Make;
Please correct me if i am wrong
Related
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.
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.
I have a dll where i would like to access the global variables of the Project.
How can this be done in VB6?
You can not access anything in a different project unless you explicitly pass it between the projects via COM.
While it is syntactically correct to use a global variable it is a very poor idea. Add either a module or a class file and encapsulate your variable inside a property. If you want to access your properties from within your project a bas file is fine. If you are describing making an ActiveX dll and accessing properties with another, separate project you should make a class module. You will need to set the class Instancing property to something other than private.
'myproject.bas code
Option Explicit
private mblnIsDirty as boolean
Public Property Let IsDirty(ByVal vIsDirty)
mblnIsDirty = vIsDirty
End Property
Public Property Get IsDirt() As Boolean
IsDirty = mblnIsDirty
End Property
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.
there is something I try to understand. I have this object declaration in my AppsController-Class for a Cocoa Application
NSMutableArray *personArray;
In can put this declaration inside the Header file or inside the implementation of the class in the code file. It makes no difference. I can even put it outside the #implementation context right under the #import commands.The Application works just fine.
Since I don't inherit from the AppsController Class or do anything else fancy with it I wonder what might be the difference between these types of declarations?
Where does the declaration really belong?
It depends on how you want to use the variable. If you place the variable declaration inside the interface for your class, each instance of your class will have its own copy of the variable, which is kept separate from all other instances of your class:
#interface AppsController : NSObject
{
NSMutableArray *personArray;
}
Each instance of the AppsController class will have its own copy of the personArray variable, which is separate from all other instances of the class.
If, however, you define the variable outside of the interface, it becomes a global variable, and it is a shared (instances of your class do not get their own copy), and can be accessed from any instance of your class. If you declare it in the header as such:
NSMutableArray *personArray;
it is also visible to methods in other files and classes that include your header.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
Since your object is a controller object, I am guessing that you only have one instance of it present in your application. You should declare the variable either:
As an instance variable if your personArray variable needs to be unique to each instance of your controller class (even if you only have one instance now, you may have more than one instance of it in future).
As a class variable (using the static keyword) if you want the variable to be visible to all instances of your class, with only one, shared instance of the variable.
As a global variable if you want the variable to be a single instance (not unique to instances of your class) and also visible to other classes or code in other files.
You should probably put it in the interface section of the header file, that way there will be one instance of it per object instantiated. Which I presume is your intention.
I think if you put it elsewhere it will be treated as a global variable. Ie, there will only ever be one instance of personArray, and it will be visible from anywhere in your application.
Your application is probably working fine, because you only have one instance of your AppsController Class, and no other variables called personArray. If you ever need a second AppsController, or another variable elsewhere called personArray, you'll run into problems.
If you declare the variable in the implementation file, but outside of the implementation itself, and prefix it with the static keyword, the variable will only be visible to the implementation of your class. This is common when you want a variable that is visible to you all of class instances, but not visible to anyone else, and is a way to create class variables.
just to clarify, the reason variables declared inside the implementation file but outside the implementation section are not available outside the class, is because other classes are not aware of anything inside the implementation file. your import statements refer to headers, not their implementations, so they know nothing of those implementation file declarations.
anyway, to create a static variable accessible only by a class, use keyword static when making a declaration in an implementation file. you can put it at the top of the file, at the top of the implementation section, or inside a function, depending on what you want the scope to be.
edited: corrected, thanks peter