Whats the difference between property and property with instance variable? [duplicate] - objective-c

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Properties and instance variable declaration
Whats the difference between the following two:
SomeClass.h
#interface SomeClass : NSObject {
NSString *someString;
}
#property (strong, nonatomic) NSString *someString;
#end
SomeClass.h
#interface SomeClass : NSObject
#property (strong, nonatomic) NSString *someString;
#end
I know whats the difference between the declaration inside the { } after the interface and a property is, but whats the difference between using both and using just a property?

Since the LLVM version 4.2 compiler there is no longer a difference. You no longer HAVE to declare a property variable inside the {}.

{
NSString *someString;
}
This is an ivar.
#property (strong, nonatomic) NSString *someString;
This is a property which creates setter and getter (accessors). Also one class instance with same name is created for you.
EDIT:
If you only use ivar, you cant use self.ivar name.
You have to use by _ivar, means directly to the ivar.
Inside { & } are protected. While #property are public.

Related

#property hides _ivar when setter and getter are custom [duplicate]

This question already has answers here:
Adding a getter makes using an underscore incorrect syntax
(3 answers)
Closed 7 years ago.
#import "AppDelegate.h"
#interface AppDelegate ()
#property (strong, readwrite, nonatomic) NSNumber *currentNumber;
#end
#implementation AppDelegate
- (NSNumber *)currentNumber {
}
- (void)setCurrentNumber:(NSNumber *)currentNumber {
}
Why I can't access _currentNumber in currentNumber?
If I will remove setCurrentNumber then I can access _currentNumber in currentNumber?
The #property does not cause the ivar generation; rather, it's the implicit #synthesize. However, when you implement both the getter and setter, there is nothing to (implicitly) synthesize, so clang doesn't bother. If you add an explicit #synthesize statement, you'll get your ivar.
Like Avi mentioned, there is #synthesize keyword. If you just declare property(without implementing getter and setter for it) the corresponding ivar will be generated. Its name will be [underscore][property_name].For example declaring #property currentNumber; leads to implicit applying `#synthesize currentNumber = _currentNumber;
But if you want to assign ivar with another name to your property you can declare this ivar and synthesize the property with it:
#interface AppDelegate ()
{
NSNumber *_anotherIvar;
}
#property (strong, readwrite, nonatomic) NSNumber *currentNumber;
#end
#implementation AppDelegate
#synthesize currentNumber = _anotherIvar;
#end
#synthesize tells the compiler to create corresponding getter and setter which are backed by ivar on the right side of assignment. And if you provide your own setter - you prevent compiler from creating implicit synthesize(and generating ivar), so you need to provide ivar by yourself somehow(for example use explicit synthesize).
Here is good explanation about #synthesize.

Objective-C existing instance variable must be __unsafe_unretained error [duplicate]

This question already has an answer here:
Existing ivar 'title' for unsafe_unretained property 'title' must be __unsafe_unretained
(1 answer)
Closed 9 years ago.
Same code are already questionned here, but I deal with a different problem that I can't solve myself probably because i'm new with Objective-C, so I decide to ask the question :)
webberAppDelegate.h:
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#interface webberAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
WebView *webber;
}
#property (assign) IBOutlet NSWindow *window;
#property (assign) IBOutlet WebView *webber;
#end
webberAppDelegate.m:
#import "webberAppDelegate.h"
#implementation webberAppDelegate
#synthesize window;
#synthesize webber;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSString *urlString = #"http://www.apple.com";
// Insert code here to initialize your application
[[webber mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
}
#end
So, in webberAppDelegate.m, here's my problem with this fraction I suppose:
#synthesize window;
#synthesize webber;
who give me this long error:
Existing instance variable 'window' for property 'window' with assign attribute must be __unsafe_unretained
and pratically the same for other var "webber":
Existing instance variable 'webber' for property 'webber' with assign attribute must be __unsafe_unretained
Thanks for your help, I really appreciate Stackoverflow community for days !!
The default ownership qualification for instance variables in ARC is strong, and like #robMayoff mentioned assign is the same as unsafe_unretained so your code reads like the following:
#interface webberAppDelegate : NSObject <NSApplicationDelegate> {
__strong NSWindow *window;
__strong WebView *webber;
}
#property (unsafe_unretained) IBOutlet NSWindow *window;
#property (unsafe_unretained) IBOutlet WebView *webber;
As mentioned in the linked answer provided by #Firoze, the property declaration and iVar should have matching ownership qualification. So the solution would be to make the __strong in the above code to __unsafe_unretained or to remove the instance variable declarations completely so that the compiler takes care of it.
The same solution is provided in the linked answer in the comment. Just adding some info.

Subclass of class with synthesized readonly property cannot access instance variable in Objective-C

In the superclass MyClass:
#interface MyClass : NSObject
#property (nonatomic, strong, readonly) NSString *pString;
#end
#implementation MyClass
#synthesize pString = _pString;
#end
In the subclass MySubclass
#interface MySubclass : MyClass
#end
#implementation MySubclass
- (id)init {
if (self = [super init]) {
_pString = #"Some string";
}
return self;
}
The problem is that the compiler doesn't think that _pString is a member of MySubclass, but I have no problem accessing it in MyClass.
What am I missing?
The instance variable _pString produced by #synthesize is private to MyClass. You need to make it protected in order for MySubclass to be able to access it.
Add an ivar declaration for _pString in the #protected section of MyClass, like this:
#interface MyClass : NSObject {
#protected
NSString *_pString;
}
#property (nonatomic, strong, readonly) NSString *pString;
#end
Now synthesize the accessors as usual, and your variable will become accessible to your subclass.
I am familiar with this problem. You synthesize the variable in your .m class, so it is not imported along with the header since the _pString variable will be created as part of the implementation, and not the interface. The solution is to declare _pString in your header interface and then synthesize it anyway (it will use the existing variable instead of creating a private one).
#interface MyClass : NSObject
{
NSString *_pString; //Don't worry, it will not be public
}
#property (nonatomic, strong, readonly) NSString *pString;
#end
The given answer works perfectly fine. This is an alternative answer, that apparently Apple likes a bit more.
You can define a private extension of your class, a MyClass+Protected.h file, which needs to be included in MyClass.m and MySubclass.m.
Then, in this new file, you redefine the property as readwrite.
#interface MyClass ()
#property (strong, readwrite) NSString * pString;
#end
This alternative allows you to use the accessor self.pString rather than the ivar _pString.
Note: you still need to keep the definition of pString in your MyClass.h as is.

Defining intance variable and #property [duplicate]

This question already has answers here:
What's the purpose of an ivar when a property exists?
(3 answers)
Closed 8 years ago.
What is the difference between the following ways of defining variables?
#interface MyClass: NSObject
{
NSString *string;
}
#property (nonatomic, strong) NSString *string;
vs.
#interface MyClass: NSObject
#property (nonatomic, strong) NSString *string;
I know that #property takes care of setter and getter (in conjunction with #synthesize) and I know that both ways work fine.
I also know that the latter way does not work for NSArray, NSDictionary. But it works for IBOutlets linked to IB.
Does it have anything with alloc/init? or maybe there is a concept that I am missing totally?
Thanks.
The compiler will automatically create the NSString *string; ivar for you. There is no difference under the latest SDK.
I've never ran into issues with NSDictionary not being backed by an explicit ivar.
Update:
Here is the docs on declared properties.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

Class declaration in Objective C. What is the difference? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Properties and Instance Variables in Objective-C 2.0
Objective-C Properties with or without instance variables
What is the difference between the following two pieces of code? Both are compilable and I don't know which is "correct".
#interface JTPlayer : NSObject {
NSString *userId;
NSString *name;
BOOL inBattle;
}
#property (nonatomic, copy) NSString *userId;
#property (nonatomic, copy) NSString *name;
#property (nonatomic, assign) BOOL inBattle;
#end
and
#interface JTPlayer : NSObject
#property (nonatomic, copy) NSString *userId;
#property (nonatomic, copy) NSString *name;
#property (nonatomic, assign) BOOL inBattle;
#end
One is the previous version of declaring properties. As you can see, you needed to declare variables by hand, and then declare properties applied to those variables.
The second is the newer version that manages the rest for you, declaration of variables and correspondences with properties.
Both blocks are correct, but the first one requires more keystrokes. This code (both versions) is supposed to belong to a header file, accompanied with a source file with .m extension that contains the implementation. This implementation will contain #synthesize instructions, that generate the getter and setter methods for you.
For more information, you really should read the Apple Guide to Objective-C. Also check out http://www.raywenderlich.com .
The current version of the Objective-C runtime does not require you to specify you instance variables for properties. #synthesize will add them for you automatically.
Check out this article that I put up awhile ago. It explains about instance variables and properties.
Objective-C Properties with or without instance variables