I am having a problem with method naming. I want to follow the method naming format as seen in UITableViewDataSource:
- (int)numberOfSectionsInTableView:(UITableView *)tableView;
but my class name is much longer than 'UITableView' -- it's XYPagedContentScrollView where XY is the class prefix for the project. I have a delegate protocol:
#protocol XYPagedContentScrollViewDelegate <NSObject>
- (CGFloat)defaultPageHeightForPagedContentScrollView:(XYPagedContentScrollView *)pagedContentScrollView;
#end
and this method name looks ridiculously long. I know it is not a strict rule, but I just wonder is there any way to deal with the long name and still conform to Apple's naming convention? Something like:
#protocol XYPagedContentScrollViewDelegate <NSObject>
- (CGFloat)defaultPageHeightForPagedContentScrollView:(XYPagedContentScrollView *)pagedContentSV;
#end
or even:
#protocol XYPagedContentScrollViewDelegate <NSObject>
- (CGFloat)defaultPageHeightForPCScrollView:(XYPagedContentScrollView *)pagedContentSV;
#end
Can anyone help?
The length of a method is not limited by the language in any way, so feel free to make it as long as you want.
It may look bad at first, but the more verbose it is, the less chance you have of conflicts later down the line.
My rule is, if it looks like it could conflict with another method (especially if it's a delegate method), it needs a longer name.
Now, with that said, don't make names ridiculously long,so that they are 100s of characters in length, like this:
-(void) fooBarViewController:(FooBarViewController *) controller didTapRightMarginAtPoint:(CGPoint point) ofPage:(NSUInteger) page lengthHeld:(NSTimeInterval) tapLength fingers:(NSUInteger) fingerCount;
Instead, consider wrapping it in a dictionary of the event details:
-(void fooBarViewController:(FooBarViewController *) controller didTapMargin:(NSDictionary *) eventDetails;
/* eventDetails should contain the following information:
which margin?
touch location
page index
touch length
finger count
*/
This simplifies the method signature, and allows the receiver to only pull out the variables they need.
Personally, I would go with the long form: that's what autocomplete is for. That being said, if you do want to shorten it, I would drop adjectives. Something like:
#protocol XYPagedContentScrollViewDelegate <NSObject>
- (CGFloat)defaultPageHeightForScrollView:(XYPagedContentScrollView *)pagedContentSV;
#end
I wouldn't worry about name conflicts with delegate methods because if an object is ever the delegate of two different object with the same delegate methods, then it will use the passed (i.e. calling) object to distinguish them. (For example, If you're the delegate of two scroll views, you just test the passed view to find which scroll view it's talking about.)
Related
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.
I am watching the Stanford University iPad and iPhone application Developments course video. The instructor says in the video we can control-drag an UI object to the implementation files to create an action. But in this way the method will not declare in the header file. Does this mean it is ok to implement methods in the .m file but not declare in the .h file?
Depends on how you define "ok" :-)
Objective-C uses dynamic method lookup and does not really enforce access ("private", "public", etc.) specifiers. So you don't need to declare any method in a header file.
However you will end up fighting the compiler as it does do a fair amount of type-checking unless you persuade it not to, and you'll lose by doing so.
You are not required to declare in the header file all methods in the implementation. But if not in the header file obviously you cannot reference them by literal name in another file, nor can you "forward reference" them in the implementation file.
(Note that this is not that different from regular C, but is different from methods of a class in C++.)
It's "OK" to not declare methods in the header yes, under certain circumstances. For instance, if using ARC then the compiler generally needs to know the method signature so it can do the right thing. But basically all it means is that wherever you're using the method, it must already know about the method you're calling.
Since you're talking about Interface Builder, that's slightly different in that it will know about all methods since it can "see" the whole context of your header and implementation files and know that a method exists. i.e. in my terminology above, the method has been defined before it's used.
With regard to defining before use, the general accepted approach is to either:
Define a method in the interface file (.h). e.g.:
MyClass.h
#interface MyClass : NSObject
- (void)someMethod;
#end
MyClass.m
#implementation MyClass
- (void)someMethod {
// do something
}
#end
Define a method in a class continuation category. e.g.:
MyClass.h
#interface MyClass : NSObject
#end
MyClass.m
#interface MyClass ()
- (void)someMethod;
#end
#implementation MyClass
- (void)someMethod {
// do something
}
#end
I am trying to improve the design of my App by using private methods. Coming from .NET I am a little confused because I am declaring these methods in the .m file but from other files they are still showing up i.e. they are still accessible.
.m file:
#interface NSContentWebServiceController (private)
- (NSString *)flattenHTML:(NSString *)html;
- (NSString *)cleanseStringOfJsonP:(NSString *)jsonP;
- (void)retrieve:(NSasdf *)hasdel :(NSDictionary *)rootList;
- (NSString *)removeHTMLTagsFromString:(NSString *)aString;
#end
As JoostK said, there are no private methods in Objective-C like you have them in C++, Java or C#.
On top of that, the expression #interface NSContentWebServiceController (private) defines a so-called category in Objective-C. The term private here is merely a name for the category and has no meaning. Having something like yellowBunny in here would yield the same effect. A category is merely a way to break down a class into several pieces, but at runtime all categories are in effect. Note that a category is only able to add new methods to an object class, but not new variables.
For private categories it's now preferred to use the anonymous category, as in #interface MyClass(), as you then don't need a separate #implementation MyClass(yellowBunny) block but can just add the methods to main #implementation block.
See the "Categories" section in the Wikipedia entry on Objective-C for more information.
Private methods are only private in a way that they're not documented in a header file. Because of this you can't #import them into your project and thus will the compiler warn you about a 'selector not recognized' or something like that.
You'll be able to call these methods just as public methods, since it's just where you declare the prototype that makes a method private, Objective-C doesn't have such a thing as hidden, really private, methods.
At runtime, you will always be able to find all methods using introspection, so there really is no way of completely hiding your methods/properties.
You could add a id _internal instance variable which points to an object that does all the work, that way it's a bit more tough to call the private methods, although not impossible.
If two different Categories having same method, then which one will be invoked by objective C runtime system ??
for example:
#interface ClassA (MathOps)
-(void)CategoryMethod;
#end
#interface ClassA (MathOps1)
-(void)CategoryMethod;
#end
#implementation ClassA(MathOps1)
- (void) CategoryMethod{
NSLog(#"Inside Category Method 2");
}
#end
#implementation ClassA(MathOps)
- (void) CategoryMethod{
NSLog(#"Inside Category Method 1");
}
#end
Now if i am calling, [ObjClassA CategoryMethod];, Then which one called ? Why ?
It's undefined. It depends on which category gets loaded first by the runtime, are there's no documented order in which that happens.
Bottom line: don't do this. :)
As #Dave DeLong states, the behavior is undefined. One of the methods will "win", and there's just no way to know which one. If any other code depends on the loosing method, you'll find yourself debugging some potentially weird errors. Best to avoid the situation all together. This is a particular problem when implementing "obvious" helper methods. If those methods get added in a future framework version, your category will either override the new method in the class (if it's in the main class body) or may override the method if its added in a category. Eek.
Many Cocoa frameworks that provide categories for existing (e.g. Cocoa) classes follow a pattern whereby they prepend their class prefix to the method in order to minimize the chance of name collision. So, for example, you would create categories like:
#interface NSObject (MyCategory)
- (void)myprefix_categoryMethod;
#end
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.