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

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.

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.

How to view data from NSTextField Correctly?

Hi i've recently completed a tutorial book on the basics of objective c. And now I'm "Attempting" to make a simple application. Right now I seem to be having the simplest issues which i cannot seem to fix, maybe you could tell me what i'm doing incorrectly.
AppDelegate.h
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
- (IBAction)saveData:(id)sender;
//Below is a simple IBOutlet which I try to retrieve data from when the IBAction saveData occurs
#property (weak) IBOutlet NSTextField *foodName;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
//Here is the saveData IBAction which should print out the value of the NSTextField if the user entered a value (if not returns null)
- (IBAction)saveData:(id)sender {
NSLog(#"%#", foodName.stringValue);
NSLog(#"Saved");
}
#end
The problem I seem to have is the build will fail and give me an error message on this line in AppDelegate.m:
NSLog(#"%#", foodName.stringValue);
the error message is: Use of undeclared identifier 'foodName'; did you mean '_foodName'?
Could someone please explain whats going on and how I can overcome this?
To address the getter method, use self.:
NSLog(#"%#", self.foodName.stringValue);
Also, a minor point: group all your #property declarations together at the start of the #interface statement, but after any instance variable declarations:
#interface MyClass : NSObject {
NSString *_str1;
int _i1;
}
#property (weak) IBOutlet NSString *something;
#property (strong, readonly) NSNumber *somethingElse;
- (int)aMethod:(NSString *)string;
- (void)anotherMethod;
#end

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

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.

Recommended way to declare delegate properties with ARC

I used to declare all delegate properties as
#property (assign) id<FooDelegate> delegate;
I was under the impression that all assign properties should now be weak pointers, is this correct?
If I try to declare as:
#property (weak) id<FooDelegate> delegate;
I get an error while trying to #synthesize (autogenerated weak properties are not supported).
What's the best practice in this case?
Xcode 4 Refactor > Convert to Objective-C ARC transforms:
#interface XYZ : NSObject
{
id delegate;
}
#property (assign) id delegate;
...
#synthesize delegate;
into:
#interface XYZ : NSObject
{
id __unsafe_unretained delegate;
}
#property (unsafe_unretained) id delegate;
...
#synthesize delegate;
If I remember correctly it is also mentioned in WWDC 2011 video about ARC.
Use __unsafe_unretained instead weak for ARC projects targeting iOS 4 and 5. The only difference is that weak nils the pointer when deallocated, and it's only supported in iOS 5.
Your other question is answered in Why are Objective-C delegates usually given the property assign instead of retain?.

Objective C - Get a class to return a value

I rarely ask questions, but this one is frustrating me as I can not find an answer anywhere!
I just need to call the function in GameChallenges.m and return the value to the view controller. GameChallenges.m will be called by different view controllers, thats why its separate. Please help!
I have a separate class file called GameChallenges.
This has a function/method in it:
in the .h
#class StatsViewController;
#interface GameChallenges : NSObject {
StatsViewController* statsController;
NSString* challengeTitle;
}
#property (nonatomic, retain) IBOutlet StatsViewController* statsController;
#property (assign) NSString* challengeTitle;
-(NSString*)checkChallenge:(int)challegeID;
#end
in the .m
#import "GameChallenges.h"
#import "StatsViewController.h"
#implementation GameChallenges
#synthesize challengeTitle,statsController;
-(NSString*)checkChallenge:(int)challegeID{
if(challegeID==1){
self.challengeTitle = #"Some Text.";
return challengeTitle;
}else if(challegeID==2){
self.challengeTitle = #"Some Other Text.";
return challengeTitle;
}
}
From a view controller called StatsViewController I am calling this method
in the .h
#class GameChallenges;
#interface StatsViewController : UIViewController {
UILabel* challengeIDDescText;
}
#property (nonatomic, retain) IBOutlet UILabel* challengeIDDescText;
#property (nonatomic, retain) IBOutlet GameChallenges* challenges;
#end
in the .m
[challenges checkChallenge:tempString];
challengeIDDescText.text = challenges.challengeTitle;
Your code is quite weird, I'd say this is what's happening:
-[GameChallenges checkChallenge] seems to expect an int and you call it with a variable called tempString that I guess is an NSString *. More likely than not, your method is ending without assigning challengeTitle and without a valid return value. Fix it with return nil as last statement and passing an int.
This kind of problems are very easy to solve using the debugger.
Also, have a look to Apple samples.
I'm beginner in objective-C, however, code in the GameChallenges.m looks weird to me... Wouldn't this be better?
challengeIDDescText.text = [challenges checkChallenge:challengeId];