Objective-C : Accessing fields in implementation - objective-c

Is it possible to fields defined only in implementation but not in interface definition ?
#interface MyInterface .... #end --> dict not defined here!!!
#implementation MyInterface
...
NSDictionary *dict;
...
#end
In this case if somewhere I somehow accessed to this class, can I access to the dict or should I create a getter just like in Java ?
Edit after #Rob's answer
Thanks for the answer Rob, I wish I have the implementation of these interface and classes. Instead I am trying to bind two different libraries ( I know it is reallllly bad as architectural point of view but this is where I end up).
Basically, I am in react-native world. And we are using react-native-video as our player layer. But since AVPlayer does not support some subtitle types our head company sent us a library that needs a player instance and a view instance to draw subtitle on the view. I believe they will bind to events of the player and draw sub titles based on player states.
So react-native-video is in this github repo with the interface and implementation.
I find the UIView that includes the properties and casted it to the object itself RTCVideo in this case). But now I am stuck. I can go and change some stuff as per your suggestion in the "Development Pods" to be able to access but this is my last bullet :) I prefer to convince these two libraries in a friendly way :)

Yes, but the above syntax isn't what you want. The modern way to do this is with a class extension.
Your header file is the same:
#interface MyInterface
#end
But in your .m file, you create an extension by appending ():
#interface MyInterface ()
#property (nonatomic, readwrite) NSDictionary *dict;
#end
Now, inside your .m file, you can access self.dict normally, but outside of your .m file it won't appear available.
For full details, see Programming with Objective-C: Class Extensions Extend the Internal Implementation.
The syntax you've written actually creates a static (global) variable called dict that isn't tied to any instance.
It is possible to create raw instance variables using a {...} syntax, either on the extension or on the implementation, but this isn't used that often today, except for managing raw buffers that you don't want accessors for. The syntax is either:
#interface MyInterface () {
NSDictionary *_dict;
}
...
#end
or on the implementation:
#implementation MyInterface {
NSDictionary *_dict;
}
...
#end
But I recommend simple extensions with properties any time you can. And if you are considering creating an accessor for it, you definitely want to use #property and let the system do it for you.
If I understand your edits correctly, you're trying to read the internal ivars of an object that doesn't expose them with an accessor, correct? I believe specifically you want to access _player.
There's several common ways to do that. The key feature you want is Key-Value Coding.
The simplest approach for this problem is -valueForKey:
AVPlayer *player = [view valueForKey:#"player"];
The first thing -valueForKey: looks for is _<key>, and if it's just an object pointer (as in this case), it just returns it.
(This can be broken if a class return false for +accessInstanceVariablesDirectly, but the default is true, and it's unusual to override this.)
Another very common approach is to just declare any methods you know exist as a category. (This won't work for _player, since it's not a method, but in case you need similar things.) Imagine you wanted to call the "private" method -removePlayerTimeObserver. In your .m file, just say you know about it using a category:
#interface RCTVideo (PrivateMethods)
- (void)removePlayerTimeObserver;
#end
And since you know about it, you can call it:
[video removePlayerTimeObserver];
If you're wrong, and that method doesn't really exist, then the program will crash. In Objective-C, almost all rules are advisory. You can break them if you want to. ObjC programmers tend to be big rule-followers because otherwise the program crashes and ObjC has very clear rules that are pretty easy to follow. It's not because the system forces us to.

Related

How to access protected variable in Objective-C?

I know protected variable can't be access out side the class but is it possible to access them in Category or in SubClass, I think it's not possible for Subclass but is it the same case for Category ?
What I want to do is some modification to a library form github but I don't want to modify the original source code. I want to achieve this through subclassing or using category but the problem is I want reference to some protected variable.
Protected variable in .m file:-
#interface Someclass() {
NSMutableDictionary *viewControllers;
__weak UIViewController *rootViewController;
UIPageViewController *pageController;
}
#end
A category cannot access private instance variables nor can a subclass do that.
As you have access to the source code and just don't want to change the original source code you could create another class with exactly the same data structure. (same variable names and types declared exactly in the same way and sequence).
#interface Shadowclass() {
NSMutableDictionary *viewControllers;
__weak UIViewController *rootViewController;
UIPageViewController *pageController;
}
#end
Then add getters and setters to Shadowclass to make the values accessible.
The do:
Someclass *someclass = ... // you get the object from somewhere somehow.
object_setClass(someClass, [ShadowClass class]);
How someclass is of the type ShadowClass and you can access the getter and setter. Frankly I am not sure how the current compiler allows for accessing the getters directly of if you are allowed to cast someClass now an ShadowClass type object variable, but you can use performSelector for accessing the getters or setters.
Accessability of getters and setters directly like [shadowClass rootViewController:xxx] may even vary whether you are using ARC or not. (The compiler's behaviour here may even be configurable. This, too, I do not know on detail out of the top of my head.)
However, I am not sure whether I really want to recommend that! You may find less "hacky" alternatives.
And do not underestimate the importance of creating exactly the same structure for Shadowclass as for Someclass!

Objective C shenanigans

In my quest to be the grandmaster of Objective C, I keep running into it's subtleties, which I want to share with ya'll and gain an understanding why
1) I have two init methods, the one that is inherited by NSObject for my Objective C class and one is a custom method that I create off my own, let's say
initCustomMethod:(int)par1 argument2:(int)par2;
My Aim is to call initCustomMethod through the provided init method, essentially
-(id)init{
return [self initCustomMethod:1 argument2:3];
}
Naturally, maintaining the order, I have init appearing before initCustomMethod in the .m file. Xcode warns me telling me that the initCustomMethod is not found, I go ahead and shuffle the order and have init appearing after initCustomMethod is declared and there is no such warning message anymore and everything is fine.
I concur that the order is important since it's essentially derived from C, however I am not sure of this. Because, i shuffled the order of some properties and their custom methods, with the properties #synthesize being declared after the custom setter method for a given property, but there was no such error replica.
Can anyone point out the malice here?
Thanks guys!!!
Very cool guys, thanks for helping me out with this. Also, since I have a custom init method, I am initializing the super in this method and using the original init method to call the custom init method.
Anything wrong with this?
Before you reference it anywhere, you should declare initCustomMethod:argument2 in your interface, which would usually be in your header file.
For example, you would usually have a .h file that looks like:
#interface MyClass
{
//instance variables
int anInstanceVariable;
}
// properties
#property (nonatomic, assign) int aProperty;
// methods
-(id)initCustomMethod:(int)par1 argument2:(int)par2;
#end
And if you did this, the order in which you define init and initCustomMethod:argument2: won't matter. This is because the declaration tells the compiler that you are going to define the method, and what it will look like, so it isn't confused when you use it later.
It's a bad idea in Objective-C to use a function or a method before it is either declared or defined. Putting initCustomMethod:argument2: before init means that the former is already defined in the latter. But if you'd just declare it in the header, it wouldn't matter which order they went in.
Add your custom method name in your header file - the compiler just goes through things in order. If you don't have a forward declaration, the compiler won't know what to do with that call. You're going to need to put it in the header if you want other parts of your program to be able to call it anyway.

Unexpected content in default files generated for opengl template in xcode

I was just starting a new opengl project in xcode. When I was going through the default files created, I was confused by this following line of codes in the viewController interface.
#interface RetinaTestViewController ()
#property (nonatomic, retain) EAGLContext *context;
#property (nonatomic, assign) CADisplayLink *displayLink;
- (BOOL)loadShaders;
- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file;
- (BOOL)linkProgram:(GLuint)prog;
- (BOOL)validateProgram:(GLuint)prog;
#end
My question is why this is written in the implementation of viewController rather than in the interface itself. This may be very basic but I just started to work with the openGL stuff. Please do help.
I don't think this is really OpenGL related, but Objective-C has something called categories, which allow you to add extra methods to an existing class. You can add them to any class you want, whether you have the source code or not. The syntax looks like:
#interface classname (categoryName)
- (void)extraMethod1;
- (void)extraMethod2;
#end
#implementation classname (categoryName)
- (void)extraMethod1
{
}
- (void)extraMethod2
{
}
#end
And, as I say, you can use that to add methods to any class, including e.g. NSString, NSDictionary and the other Foundation objects.
The brackets after the classname in the interface declaration dictate that this is a category, not a full interface definition. Historically there was no way to add extra storage to a class through a category, so you may not declare member variables in categories. Hence there's no {} section.
In the modern runtime (on 64bit OS X and iOS), you can add extra storage via #properties, as Apple appear to do in the code you've given.
Here Apple are using category methods to create something like private methods — in this case methods that everyone in the class knows are there but which aren't declared externally. That's a design decision, to keep the bits that other people are likely to look at neat and to indicate the programmer's intent.
What's going on is that:
the bits of RetinaTestViewController that Apple want everyone else to know about are declared in the header file
the bits that aren't meant to be exposed are declared only in the implementation file
A well-designed object should expose a public interface and conform to that interface, while doing whatever is necessary internally and keeping its internals secret.
You can read a little more category methods here, here and here (scroll down to number 11).

Process of transitioning a project from a collection of classes to a .dylib?

I've been working on a pet project for a few weeks now, and starting to think that it may get used by myself and a few friends. At present, it's really just a pile of Objective-C classes in an XCode project with a main() I've been using to test various features. Going forward it seems easiest to use this library in projects if I package it up as .dylib file. As I've found with other languages, doing this as an afterthought is a nuisance that ideally is farmed out to the lowest rung. :)
I'm very new to the Objective-C/Xcode world, but according to Apple's "Dynamic Library Programming Topics", I'm under the impression that it's really just a matter of rejigging my interface files to be of the format:
#protocol Person
- (void)setName:(NSString*)name;
- (NSString*)name;
#end
#interface Person : NSObject <Person> {
#private
NSString* _person_name;
}
#end
(taken from referenced Apple doc).
Where: I'm defining a protocol that contains the methods I wish to include for the classes to be contained in the .dylib, and then defining an interface that subclasses NSObject implementing the aforementioned protocol and declaring ivars in here.
A few questions:
Am I able to omit methods from the protocol that I don't wish to "EXPORT" to the dylib?
If I have subclasses of a class within the dylib, do I create another protocol for the subclass, and make the superclass of the newly created class implement that protocol? For instance, if I were subclassing person:
#protocol CatPerson
/* any additional methods for CatPerson not in Person */
- (void) protractClaws;
- (void) retractClaws;
#end
#interface CatPerson : Person <CatPerson> {
#private
/* any additional ivars for CatPerson not in Person */
NSNumber *clawCount;
}
It's likely a very trivial question, but I'm trying to figure out everything I'll need to do before I go thru the gnashing of teeth of moving all the classes to a .dylib.
Project->New Target… select "dylib" in the panel that you get. Make it the current target. control-click on the groups & files tableview header, check "target membership". Check the boxes next to the files you want included in your dylib.

How do you name your instance/param values?

Being new to Objective-C (but a long term C/++) programmer I'm looking for advice/recommendations on naming conventions for variables.
My personal preference would be to utilize a prefix for instance variables both for clarity within functions and to prevent shadowing of function parameters. However I'm a fan of properties which rules out prefixes (unless you also prefix your property names, which doesn't work too well and looks daft). Similarly I could use the "self.variable" convention, but only if I make EVERYTHING a property.
So given the code below what's your preferred naming style for instance/function variables? And if you don't bother, how do you deal with shadowing on function params?
#interface GridItem : NSObject
{
CGRect _rect;
...
}
#end
-(void) initFromRect:(CGRect)rect
{
_rect = rect;
...
}
Cheers!
Most Cocoa projects use underbar as a non-IBOutlet instance variable prefix, and use no prefix for IBOutlet instance variables.
The reason I don't use underbars for IBOutlet instance variables is that when a nib file is loaded, if you have a setter method for a connected outlet, that setter will be called. However this mechanism does not use Key-Value Coding, so an IBOutlet whose name is prefixed with an underbar (e.g. _myField) will not be set unless the setter is named exactly like the outlet (e.g. set_myField:), which is non-standard and gross.
Also, be aware that using properties like self.myProp is not the same as accessing instance variables. You are sending a message when you use a property, just like if you used bracket notation like [self myProp]. All properties do is give you a concise syntax for specifying both the getter and setter in a single line, and allow you to synthesize their implementation; they do not actually short-circuit the message dispatch mechanism. If you want to access an instance variable directly but prefix it with self you need to treat self as a pointer, like self->myProp which really is a C-style field access.
Finally, never use Hungarian notation when writing Cocoa code, and shy away from other prefixes like "f" and "m_" — that will mark the code as having been written by someone who doesn't "get it" and will cause it to be viewed by suspicion by other Cocoa developers.
In general, follow the advice in the Coding Guidelines for Cocoa document at the Apple Developer Connection, and other developers will be able to pick up and understand your code, and your code will work well with all of the Cocoa features that use runtime introspection.
Here's what a window controller class might look like, using my conventions:
// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
IBOutlet NSTextField *nameField;
IBOutlet NSTextField *titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#end
// EmployeeWindowController.m
#import "EmployeeWindowController.h"
#implementation EmployeeWindowController
#synthesize employee = _employee;
- (id)initWithEmployee:(Employee *)employee {
if (self = [super initWithWindowNibName:#"Employee"]) {
_employee = [employee retain];
}
return self;
}
- (void)dealloc {
[_employee release];
[super dealloc];
}
- (void)windowDidLoad {
// populates the window's controls, not necessary if using bindings
[nameField setStringValue:self.employee.name];
[titleField setStringValue:self.employee.title];
}
#end
You'll see that I'm using the instance variable that references an Employee directly in my -init and -dealloc method, while I'm using the property in other methods. That's generally a good pattern with properties: Only ever touch the underlying instance variable for a property in initializers, in -dealloc, and in the getter and setter for the property.
I follow Chris Hanson's advice in regards to the underscore ivar prefix, though I admit I do use underscore's for IBOutlets as well. However, I've recently starting moving my IBOutlet declarations to the #property line, as per #mmalc's suggestion. The benefit is that all my ivars now have an underscore and standard KVC setters are called (i.e. setNameField:). Also, the outlet names don't have underscores in Interface Builder.
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
NSTextField *_nameField;
NSTextField *_titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#property(nonatomic, retain) IBOutlet NSTextField *nameField;
#property(nonatomic, retain) IBOutlet NSTextField *titleField;
#end
You can use the underbar prefix on your ivars and still use the non-underbar name for your properties. For synthesized accessors, just do this:
#synthesize foo = _foo;
This tells the compiler to synthesize the foo property using the_foo ivar.
If you write your own accessors, then you just use the underbar ivar in your implementation and keep the non-underbar method name.
Personally, I follow the Cocoa naming conventions, using camel-casing for functions and variables, and capitalized camel-casing for object names (without the leading NS of course).
I find type prefixing makes code more opaque to anyone who didn't write it (since everyone invariably uses different prefixes), and in a modern IDE it's not really that difficult to figure out something's type.
With the introduction of properties I see no need for prefixing "_" to class instance variables. You can set a simple rule (described in your header file) that any variables to be accessed external to the class must be accessed via the property, or by using custom methods on the class to affect values. This to me seems much cleaner than having names with "_" stuck on the front of them. It also properly encapsulates the values so that you can control how they are changed.
I don't like using underscores as prefixes for any identifiers, because C and C++ both reserve certain underscore prefixes for use by the implementation.
I think using "self.variable" is ugly.
In general, I use unadorned identifiers (that is, no prefixes nor suffixes) for instance variables. If your class is so complicated that you can't remember the instance variables, you're in trouble. So for your example, I'd use "rect" as the name of the instance variable and "newRect" or "aRect" as the parameter name.
Andrew: There actually are plenty of Cocoa developers who don't use instance variable prefixes at all. It's also extremely common in the Smalltalk world (in fact, I'd say it's nearly unheard-of in Smalltalk to use prefixes on instance variables).
Prefixes on instance variables have always struck me as a C++-ism that was brought over to Java and then to C#. Since the Objective-C world was largely parallel to the C++ world, where as the Java and C# worlds are successors to it, that would explain the "cultural" difference you might see on this between the different sets of developers.
My style is hybrid and really a holdover from PowerPlant days:
THe most useful prefixes I use are "in" and "out" for function/method parameters. This helps you know what the parameters are for at a glance and really helps prevent conflicts between method parameters and instance variables (how many times have you seen the parameter "table" conflict with an instance variable of the same name). E.g.:
- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;
Then I use the bare name for instance variables and property names:
Then I use "the" as a prefix for local variables: theTable, theURL, etc. Again this helps differentiate between local and and instance variables.
Then following PowerPlant styling I use a handful of other prefixes: k for constants, E for enums, g for globals, and s for statics.
I've been using this style for something like 12 years now.
While I love using the underscore prefix for ivars, I loathe writing #synthesize lines because of all the duplication (it's not very DRY). I created a macro to help do this and reduce code duplication. Thus, instead of:
#synthesize employee = _employee;
I write this:
ddsynthesize(employee);
It's a simple macro using token pasting to add an underscore to the right hand side:
#define ddsynthesize(_X_) #synthesize _X_ = _##_X_
The only downside is that it will confuse Xcode's refactoring tool, and it won't get renamed, if you rename the property by refactoring.
Along with what's been said here, be sure to read the Cocoa documentation on Key Value Observing compliant naming. Strictly following this pattern will help you greatly in the long run.