Objective-C class extensions vs private method or variable [duplicate] - objective-c

This question already has answers here:
Where to put iVars in "modern" Objective-C?
(5 answers)
Closed 7 years ago.
Im not understanding why people use extensions to make variables private instead of just declaring them only in the implementation file ?
Take a look at this code one using extension and one using a instance variable:
//this is an extension
#interface MyClass () {
NSString *myInstanceVariable;
}
// ...
#end
or in the class implementation:
#implementation MyClass {
NSString *myInstanceVariable;
}
// ...
#end
both give me instance variables that would be private. Why would i choose a extension instead of the 2nd approach of just declaring a instance variable ?

If you are declaring variables in an #interface, it exposes details of the implementation to users of the class.
If you are declaring variables in an #implementation it keeps their existence private and is not visible to someone who only imports the h file.
Edit: For more concise answer. See here

Related

How to setup a class property in objective C? [duplicate]

This question already has answers here:
How do I declare class-level properties in Objective-C?
(10 answers)
Closed 2 years ago.
How to setup a class property that can be accessed throughout the app and from another classes in objective C?
Note: I know that there are other answers here at SO but most of then are outdated or torn apart! The question that is marked as being duplicate was asked 11 years ago ...!
Recently I had a project where dived deeper into this topic and I like to give you some code examples that may be helpful to someone out here. This is also some kind of information storage for myself :)
Since Xcode 8 you can define a class property in the header file of YourClass, using the "class" identifier like:
#interface YourClass : NSObject
#property (class, strong, nonatomic) NSTimer *timer;
#end
To use the class property in class methods in your implementation you need to asign a static instance variable to your class property. This allows you to use this instance variable in class methods (class methods start with "+").
#implementation YourClass
static NSTimer *_timer;
You have to create getter and setter methods for the class property, as these will not be synthesized automatic.
+ (void)setTimer:(NSTimer*)newTimer{
if (_timer == nil)
_timer = newTimer;
}
+ (NSTimer*)timer{
return _timer;
}
// your other code here ...
#end
Now you can access the class property from all over the app and other methods with the following syntax - here are some examples:
NSTimeInterval seconds = YourClass.timer.fireDate.timeIntervalSinceNow;
[[YourClass timer] invalidate];
You will always send messages to the same object, no problems with multiple instances!
Please find an Xcode 11 sample project here: GitHub sample code

How to write methods that should only be used within the class itself and are able to access ivars [duplicate]

This question already has answers here:
Best way to define private methods for a class in Objective-C
(12 answers)
Closed 9 years ago.
I have a class which has some methods that are only to be used within the class itself. These methods exist because I have a three-step process for the graphics work I'm doing, but I only want instances of the class to access the final result of those calculations, in a simplified example:
#import <Foundation/Foundation.h>
#interface GraphicsWorld : NSObject
#property(nonatomic, strong) NSMutableArray *objects;
#property(nonatomic, strong) NSMutableArray *adjustedObjects
/* three methods I'll never use outside of this class
I want to find a way to get replace these methods.
*/
-(void) calcTranslation;
-(void) calcRotation;
-(void) calcPerspective;
/* the one method I'll use outside of this class */
-(NSMutableArray *) getAdjustedObjects;
#end
I could define c-functions just outside of my implementation for this, but then they wouldn't have access to the properties:
#import <Foundation/Foundation.h>
#import "GraphicsWorld.h"
void calcTranslation()
{
// I'm useless because I can't access _objects.
}
void calcRotation()
{
// Hey, me too.
}
void calcPerspective()
{
// Wow, we have a lot in common.
}
#implementation GraphicsWorld
-(NSMutableArray *) getAdjustedObjects
{
calcTranslation();
calcRotation();
calcPerspective();
return adjustedObjects;
}
#end
Unless I'm misunderstanding your question, it sounds like you just want to hide your methods from being public? If so, just delete them from the header. You no longer need to declare methods in advance in objc (Xcode). The compiler will just find them internally now.
Make C-style functions (as you've shown) that take arguments and return values.
Make private Objective-C-style methods.
In addition to your #implementation section in the .h file, you can also have one in your .m file, which is private. Just as you declare methods and properties in the .h file's #implementation, you can do the same in the .m.
A method can be called whether it is declared private, or not put in the header file; due to the nature of Objective-C hiding methods is hard.
Hiding functions is a lot easier, just declare them static. To access the current instance you just pass in a reference to it - i.e. exactly what Objective-C does behind the scenes.
So for example:
void calcTranslation(GraphicsWorld *self)
{
// Access properties, instance variables, call instance methods etc.
// by referencing self. You *must* include self to reference an
// instance variable, e.g. self->ivar, as this is not a method the
// self-> part is not inferred.
}
and to call it:
-(NSMutableArray *) getAdjustedObjects
{
calcTranslation(self);
...

class method and my array [duplicate]

This question already has answers here:
What is the difference between class and instance methods?
(18 answers)
Closed 9 years ago.
I have this code:
.h
#interface DetalhesPod : UIViewController {
NSString *linhaPod;
}
#property (nonatomic, strong) NSString *linhaPod;
.m
+ (NSArray *)_tracks {
NSArray *arrTexto = [self.linhaPod componentsSeparatedByString:#"#"];
}
Why I have problem with "+" in "self.linhaPod" ? If I put "-" I don't have problem:
- (NSArray *)_tracks {
}
Error message:
instance variable "linhaPod" accessed in class method...
Thanks
What you're seeing here is the difference between a class and an instance of that class. Each instance of the class has its own linhaPod instance variable — in one instance, it might point to the string #"bob" and in another it might be #"andy". The class is an entity of its own. self in a class method refers to the class itself, not to any instance. So what would it mean to access this variable from the class itself? The instance variable only exists in instances (hence why it is called an instance variable).
You can't reference a property from a static, or class method (in your case, _tracks). This is because class methods don't operate on an object, and the notion of an object property value makes no sense if you don't have an object. Class methods can only use other class methods and static variables from the same class. Check out the Wikipedia article on static methods (this concept is common to many programming languages, including Objective-C). It's a fundamental concept in programming and really worth learning about.

Declaring variable inside and outside of #implementation [duplicate]

This question already has answers here:
Declaration/definition of variables locations in ObjectiveC?
(4 answers)
Closed 9 years ago.
I am just trying to understand life of variables with a throw away below code. I can see _inside and _outside retains when about instantiate new instance, while braces are not.
#interface ViewController (){
NSString *_innBraces;
}
#end
NSString *_outside;
#implementation ViewController{
NSString *_inmBraces;
}
NSString *_inside;
-(id)initWithInside:(NSString*)inside outside:(NSString*)outside nBraces:(NSString*)nBraces mBraces:(NSString*)mBraces{
self = [super init];
if (self) {
_inside = inside;
_outside = outside;
_innBraces = nBraces;
_inmBraces = mBraces;
return self;
}else{
return nil;
}
}
Is there any difference between the place of declaration of _inside and _outside?
Any difference between braces variables from where it is declared?
Any difference between static variable declared same way vs _inside/_outside variable?
_inside and _outside are both declared as global variables.
Since you appear to be declaring everything in the same file, there's no difference between _innBraces and _inmBraces, they are both instance variables in the class. If the #interface were in a header file, then you'd see a difference in scope between the two, since the _inmBraces would only be visible in your implementation file, and _innBraces will be visible in any file that includes the .h file.
Neither of these are declared static. If they had been (preceding with the static keyword), then they would each be local in storage and namespace to the file where they are declared.
In the case of 1 and 3, they are both straight C declarations, and thus whether they are in the scope of the #implementation and #interface is doesn't make any difference. In Objective-C, there are no class variables, as such.
For class variables, the general process is to create a file-static variable of the form:
static NSString *sMyClassVariable;
within the implementation file. This variable, because it is static, will not be visible in any other file than your implementation file.

What's the logic of putting #interface in .m file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between #interface definition in .h and .m file
What is the #interface declaration in .m files used for in iOS 5 projects?
I've seen code like this:
// In Header.h
#interface Header{}
#end
// In Header.m
#interface Header()
#end
My questions are:
What's the difference in putting it in 2 files?
Why put {} after class name in ".h" file and why "()" in ".m" file?
#interface MyClass(){
NSInteger aInt;
}
#property(nonatomic,strong) NSString *name;
#end
is a class extension
with modern compilers this is a great way, to decrale methods, ivars and properties only for private use in the class MyClass.
Class extensions have to be declared in the main implementation file (not in a category).
So you can hide implementation details from the header file, they are private.
This has become a common practice for declaring "private" properties/methods for a given class. By declaring them in an anonymous class extension inside the .m, these properties/methods are not exposed to consuming objects.