Cocoa : how do you name your init parameters for not interfering with ivars? - iphone

Let's begin with an example :
#interface myClass : NSObject {
NSString * title;
}
-(id)initWithTitle:(NSString*)title;
Compiler doesn't like this because title init parameter hides myClass title ivar.
But i don't like these options :
-(id)initWithTitle:(NSString*)t;
-(id)initWithTitle:(NSString*)myTitle;
-(id)initWithTitle:(NSString*)_title;
So that's a poll: what's your convention?

Some people prefer calling their ivars _title or title_ and then they can just use title as parameter name in functions. Or you just call it aTitle or newTitle. There is no right or wrong way to do it.

I prefer to use -(id)initWithTitle:(NSString *)aTitle;.

I currently use pTitle, but used inTitle for years.

Related

is there a way to define a variable thats accessible to some classes and not others?

In objective-c, the access to variables is limited to three types which is #public , #private , #protected (default) and #package .. these access modifiers allow us to access the variable through 4 situations in order :
1- access the variable from anywhere.
2- access the variable only inside the class.
3- access the variable from anywhere in the class and its subclasses.
4- access the variable from anywhere in the framework.
my question is: is there a way to define a variable which is accessible to some classes and not others ? (i.e. customised scope for variables)
What you're asking for is C++'s friend keyword. Friend classes in Objective-C discusses the topic.
You can use class extensions to create more flexible access control:
// MyClass.h
#interface MyClass : SomeSuperclass {
int ivar;
}
#end
// MyClass-Custom.h
#include "MyClass.h"
#interface MyClass () {
int anotherIvar;
}
#end
Now anotherIvar will be accessible only to code that #includes MyClass-Custom.h. You can create more class extensions on the same class to get additional access groups.
You would have to write your own setter and getter methods.
- (id) get_abc_value:(id)from {
if ([from isKindOfClass:[SomeRespectedClass class]]) {
return abc;
}
return nil;
}

Is there a way to set variables for NSObjects without creating properties for each?

Basically, I have a custom NSObject with a lot of boolean variables. I would like to know if there is a way to modify these variables (from outside this class) without creating a property for each one. Is this possible? Thanks in advance!
Here is part of my object's header:
#interface Polygons : NSObject {
//BOOL values for attributes
BOOL parallelogram;
BOOL rhombus;
BOOL square;
...
}
Use a bitmask to represent a set of related boolean properties. First, define an enum like so:
enum GeometryFlags {
Parallelogram = 1 << 0,
Rhombus = 1 << 1,
Square = 1 << 2,
// etc.
};
You can optionally provide a corresponding typedef statement:
typedef NSUInteger GeometryFlags;
Then you can define a property to allow outside callers to access the bitmask:
// In .h file:
#property (nonatomic) GeometryFlags geometryFlags;
// In .m file:
#synthesize geometryFlags = _geometryFlags;
Calling code can then access the property to get or set the bitfield. Note that you can use the bitwise OR operator to specify multiple values:
// Uses the property accessor to modify two values in the bitmask.
someObj.geometryFlags = Parallelogram | Rhombus;
EDIT
For more info on how to work with a bitmask, see the following:
How do those bitmasks actually work?
http://en.wikipedia.org/wiki/Mask_(computing)
http://en.wikipedia.org/wiki/Bitwise_operation
It's possible with KVC, e.g.:
BOOL isParallelogram = [[myPolygon valueForKey:#"parallelogram"] boolValue];
(see Accessor Search Implementation Details in the Key-Value Coding Programming Guide)
That said, I wouldn't recommend this approach. Not only is it inefficient, but it also breaks encapsulation. This is exactly what properties are made for and there's no reason not to use them in this case.
Cant you just create a method which takes the name of the variable and the value and then assigns it to it?
You can declare them #public:
#interface Polygons : NSObject {
#public
//BOOL values for attributes
BOOL parallelogram;
BOOL rhombus;
BOOL square;
...
and then access them like this:
mypolygon->square = NO;
However, this breaks encapsulation, as #omz explained.
You could write a simple script that generates the properties for you. Here's a starting point:
grep "BOOL [a-zA-Z0-9_]+;$" Polygons.h

How do i refer to methods inside a UIVIiw?

I have imported my .h file into a 2nd one, but in the 2nd one i'm trying to do:
FirstClass *firstClass = [FirstClass alloc] init];
[firstClass iconWithType:test];
To match this:
-(void)iconWithType:(NSString *)iconType
But it's not listing iconWithType as a suggestion and i get a warning saying it might not respond to that.
How can i get this to work properly?
My FirstClass is a UIView.
In your FirstClass.h file do you have the method definition in the interface?
I.e.
#interface FirstClass : NSObject {
}
- (void)iconWithType:(NSString *)iconType;
#end
Additionally, the name of the method implies something should be returned. However, it is marked as void.
I'm guessing you just have a return type mismatch. Take a look: does -iconWithType: actually return void? or does it return a UIImage or something else besides?

Use of type 'id' in cocoa class

I want to implement a class which can be used by two classes of my project.
One is manipulating 'NewsRecord' objects.
One is manipulating 'GalleriesRecord' objects.
In another class, I may use one of the two objects so i do something like that :
// header class
id myNewsRecordOrGalleriesRecord;
// class.m
// NewsRecord and GalleriesRecord have both the title property
NSLog(myNewsRecordOrGalleriesRecord.title);
and i get :
error : request for member 'title' in something not a structure or union
any ideas :D ?
Thanks.
Gotye
How am I supposed to do it ?
You can't use dot syntax on id types because the compiler cannot know what x.foo means (the declared property may make the getter a different name, e.g. view.enabled -> [view isEnabled]).
Therefore, you need to use
[myNewsRecordOrGalleriesRecord title]
or
((NewsRecord*)myNewsRecordOrGalleriesRecord).title
If title and more stuffs are common properties of those two classes, you may want to declare a protocol.
#protocol Record
#property(retain,nonatomic) NSString* title;
...
#end
#interface NewsRecord : NSObject<Record> { ... }
...
#end
#interface GalleriesRecord : NSObject<Record> { ... }
...
#end
...
id<Record> myNewsRecordOrGalleriesRecord;
...
myNewsRecordOrGalleriesRecord.title; // fine, compiler knows the title property exists.
BTW, don't use NSLog(xxx);, which is prone to format-string attack and you can't be certain xxx is really an NSString. Use NSLog(#"%#", xxx); instead.
Try accessing the title of your record like [myNewsRecordOrGalleriesRecord title];
If you're going to be doing a lot of this type of thing (accessing common methods in two classes) you would probably benefit significantly from either creating an abstract superclass that both NewsRecord and GalleriesRecord can inherit from (if they'll be sharing a lot of code) or creating a protocol they both can adhere to (if they'll be sharing method names but not code.
The compiler is not happy since an id is actually a NSObject instance, which doesn't have a title property.
If your object is KVC compliant, you can use the valueForKey method:
NSLog( [myNewsRecordOrGalleriesRecord valueForKey:#"title"] );

iPhone ivar naming convention [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
I've noticed that in a lot of the reference materials out there, I see that a lot of the time, variables are named _variable in the .h file, then are #synthesize'd in the .m file as
#synthesize variable = _variable;
Why is this done? What am I missing?
Thanks!
There is not consensus on this. Some people like to use it for clarity to separate out class variables, and as another responder noted to avoid conflict with incoming parameter names. Even in Apple sample code the use is mixed.
However, I greatly prefer to not use the _ prefix and have two strong reasons:
1) Some people think the _ is a good indicator of "private". My take is that NO class local variable should be accessed without a setter/getter (property) and thus they are ALL private - given that why not name them in a way easier to read and use autocomplete on? Any overlap in names from parameters is quickly revealed by the compiler, and avoided through more thoughtful naming of parameters (or internal variables).
2) (even better reason) - if you use "refactor" in XCode on an internal class var that is named the same as the property used to access it, the property and synthesize statement will also be renamed. If you use refactor on a class variable prefixed with an _, the property name will not be changed - just the synthesize mapping to the internal name. I pretty much never want the name to vary from the property to the real variable it exposes access to. That alone makes me never want to use _ as a variable prefix, since being able to shift names is just about the most useful thing you can do to improve code clarity.
Using that syntax is an option to make it more clear that the ivar and property are different things.
To code external to the class, there is no difference since it uses the property.
For code in the implementation of the class itself, it can make it more clear when the ivar is used versus the property.
For example, say we have an ivar/property for an NSNumber object:
#interface MyClass : NSObject {
NSNumber *num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
#end
and now using a different name for the ivar and property:
#interface MyClass : NSObject {
NSNumber *i_num;
}
#property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
#end
#implementation MyClass
#synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
#end
Previous answers are missing the history behind this. Before Objective-C 2.0, there were no properties. So you’d have an object with instance variables like this:
#interface MyObject: NSObject {
NSArray *myArray;
}
#end
But how would you access them from other objects? the solution was to make setters and getters. But to avoid confusion, they would do it like this:
#interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
#end
The _ serves to clear up confusion between the instance variable _myArray and the method -myArray.
Sometimes people use mVarName (C++) and in Obj-c the style seems to be _varName.
One problem you can have, is imagine that your argument to a function is ...set:(int) x - BUT - you have an iVar called x...well your going to get the compiler crying about stuff like that - not to mention its confusing.
The m,_, whatever helps to show what are member properties of the class.
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
This is purely convention. I suppose its common because when you make a method getter call like this:
[myObject variable]
you are actually calling a method, not accessing a variable directly. the _ in front makes it clear that you are talking about a variable. Personally, I find this syntax annoying and distracting. I find it unnecessary, but you are right, it does appear here and there.
I prefer not to use the '_' prefix because Apple does use it consistently. By avoiding the prefix I then have greater confidence that my ivars do not collide with Apple's when I extend a cocoa touch class. Since we do not have access to the base class' source this is really the only way I know of to avoid accidental reuse of existing private ivars.
Much like
Method names beginning with “_”, a single underscore character, are reserved for use by Apple.
My preference, following Google, is simply to append an underscore and explicitly synthesize (even if I'm reimplementing):
#synthesize varName=varName_;
If I see that trailing underscore outside of init..., dealloc or an accessor, I know something's fishy.