I've declared a property called Squad, but when I send [self getSquad] I get "no visible #interface for SquadViewController declares the selector 'getSquad'".
SquadViewController.h:
#import "FlipsideViewController.h"
#import "Squad.h"
#interface SquadViewController : UIViewController <FlipsideViewControllerDelegate, UIPopoverControllerDelegate>
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (strong, nonatomic) UIPopoverController *flipsidePopoverController;
#property (nonatomic, retain) IBOutlet UILabel *squadNameLabel;
#property Squad *squad;
- (IBAction)updateTitleWithName:(id)sender;
#end
SquadViewController.m:
#import "SquadViewController.h"
#interface SquadViewController ()
#end
#implementation SquadViewController
#synthesize squadNameLabel;
#synthesize squad;
...
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
if (![self getSquad]) //<--THIS IS WHERE THE ERROR IS
{
[self setSquad:[Squad squadWithName:#"New Squad"]]; //<-- NOT HERE, SO THE SETTER SEEMS TO EXIST
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
...
I thought that "#synthesize squad" would generate getSquad and setSquad, so I'm confused.
Here's the code for Squad, if for some reason that I don't get it's relevant (I'm new to Objective C, I still find it very confusing (I'm from a java background)):
Squad.h:
#import "SquadBuilderObject.h"
#interface Squad : NSObject
#property NSString *name;
+ (id) squadWithName:(NSString*)name;
#end
Squad.m:
#import "Squad.h"
#implementation Squad
#synthesize name;
+ (id)squadWithName:(NSString *)name
{
Squad *newSquad = [[Squad alloc] init];
[newSquad setName:name];
return newSquad;
}
#end
The standard getter for a property named squad is squad, not getSquad.
The "get…" nomenclature is typically reserved for things returned by reference (e.g. - (BOOL)getSquad:(Squad **)outSquad).
Related
I'm new to xCode. I'm using xCode 4.6 and I don't understand how xcode instantiates objects fully.
I thought that if you declare the object as a property in the .h file it automatically alloc and init it. the only way I could get my code to work is to do the alloc and init on the property file. I included my sample code below, but can anyone tell me if this is the right way to do this?
#import <Foundation/Foundation.h>
#interface Person : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic) int age;
#end
#import "Person.h"
#implementation Person
#end
#import <UIKit/UIKit.h>
#import "Person.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) Person *person;
#property (weak, nonatomic) IBOutlet UILabel *lblDisplay;
- (IBAction)btnChangeLabel:(id)sender;
#end
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_person = [[Person alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)btnChangeLabel:(id)sender {
[_person setName:#"Rich"];
[_person setAge:50];
_lblDisplay.text = [NSString stringWithFormat:#"%# is %d years old.",_person.name,_person.age];
}
#end
You're doing the right thing, except in your btnChangeLabel method, refer to your properties via:
self.person.name = #"Rich";
self.person.age = 50;
_lblDisplay.text = [NSString stringWithFormat:#"%# is %d years old.",self.person.name,self.person.age];
The only time you want to use the underlying variables "_person" is when you need to allocate the space for them. The rest of the time, you'll use their accessors (getters and setters; which is what the "self.person.name =" thing is doing). This way the compiler will know to do ARC-style releases and retains automagically.
That's what I have :
Class A :
#import "ppCore.h"
#interface ppApplication : NSApplication {
ppCore* core;
}
#property (assign) ppCore* core;
#end
#implementation ppApplication
#synthesize core;
- (void)awakeFromNib
{
[self setCore:[[[ppCore alloc] init] retain]];
}
Class B :
#import "someObject.h"
#import "anotherObject.h"
#interface ppCore : NSObject<NSApplicationDelegate> {
ppSomeObject* someObject;
ppAnotherObject* anotherObject;
}
#property (assign) ppSomeObject* someObject;
#property (assign) ppAnotherObject* anotherObject;
#end
#implementation ppCore
#synthesize someObject, anotherObject;
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[self setSomeObject:[[ppSomeObject alloc] init]];
[self setAnotherObject:[[ppAnotherObject alloc] init]];
}
And here's the issue :
AT SOME LATER STAGE, in ppApplication, I'm trying to have access to core.
core is there.
But, when I'm trying to access any of core's elements (e.g. [core someObject]), everything is turning up NULL (I've checked it in the Debugger)...
What am I doing wrong??
Have you tried declaring your objects like this:
#property (nonatomic, retain) ppCore* core;
#property (nonatomic, retain) ppSomeObject* someObject;
#property (nonatomic, retain) ppAnotherObject* anotherObject;
I suggest you remove the whole core thing since you can access your delegate through [[NSApplication sharedApplication] delegate] and move the setting of someObject and anotherObject to the delegate's init method.
Antonio is right, bit you need to manage memory as well,
#import "ppCore.h"
#interface ppApplication : NSApplication {
ppCore* core;
}
#property (nonatomic, retain) ppCore* core;
#end
#implementation ppApplication
#synthesize core;
- (void)awakeFromNib
{
ppCore* tempCore = [[ppCore alloc] init];
[self setCore: tempCore];
[tempCore release];
}
This might help.
Why do you believe - (void)applicationDidFinishLaunching: on your ppCore object is ever getting called? It seems to me you'll have to explicitly invoke it from somewhere.
In this example my NSDictionary initializes with 0 key/value pairs, as shown in my debugger. It will initialize properly when I do the exact same thing in my ViewController but I would much prefer to stick to MVC design and have the NSDictionary in my model.
ShakespeareViewController.h
#import <UIKit/UIKit.h>
#interface ShakespeareViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *sonnetDisplay;
#end
ShakespeareViewController.m
#import "ShakespeareViewController.h"
#import "ShakespeareModel.h"
#interface ShakespeareViewController ()
#property (nonatomic, strong) ShakespeareModel *sonnet;
#end
#implementation ShakespeareViewController
#synthesize sonnetDisplay = _sonnetDisplay;
#synthesize sonnet = _sonnet;
- (IBAction)sonnetButton:(UIButton *)sender
{
self.sonnetDisplay.text = [self.sonnet grabSonnet:#"19"];
}
#end
ShakespeareModel.h
#import <Foundation/Foundation.h>
#interface ShakespeareModel : NSObject
-(NSString *)grabSonnet:(NSString *)atNumber;
#end
ShakespeareModel.m
#import "ShakespeareModel.h"
#interface ShakespeareModel()
#property (nonatomic, strong) NSDictionary *sonnets;
#end
#implementation ShakespeareModel
#synthesize sonnets = _sonnets;
-(NSDictionary *)sonnets
{
if (!_sonnets)
{
_sonnets = [[NSDictionary alloc] initWithObjectsAndKeys:#"19", #"19", nil];
}
return _sonnets;
}
-(NSString *)grabSonnet:(NSString *)atNumber
{
NSString *chosenSonnet = [self.sonnets objectForKey:#"19"];
return chosenSonnet;
}
#end
Any ideas on what I am doing wrong are greatly appreciated. I can't see why this wouldn't initialize with the object 19 at key value 19.
I don't see any place where you set the view controller's sonnet property to an instance of ShakespeareModel -- so when you call grabSonnet: you're sending a message to nil (and thus getting nothing back.
You should put self.sonnet = [[ShakespeareModel alloc] init] in your view controller some time before you call grabSonnet:... probably in the initializer or in -viewDidLoad.
I'm getting the error above, but unsure how to go about fixing it. This is my code:
.h:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton {
id <ColorLineDelegate> delegate;
}
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
#end
.m:
#import "ColorLine.h"
#implementation ColorLine
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#end
The error occurs in the synthesize line. I can't find a problem though.
Use this syntax:
#interface SomeClass : NSObject {
id <SomeClassDelegate> __unsafe_unretained delegate;
}
#property (unsafe_unretained) id <SomeClassDelegate> delegate;
Looks like your project might be using ARC then properties should be declared this way:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton
#property (nonatomic, weak) id <ColorLineDelegate> delegate;
#end
I had the same problem when I used old example code which did not feature ARC in my ARC project. It seems that you do not need to put the variable declarations into the interface definition any more. So your code should work like this:
h:
#import <UIKit/UIKit.h>
#protocol ColorLineDelegate <NSObject>
-(void)valueWasChangedToHue:(float)hue;
#end
#interface ColorLine : UIButton {
// Get rid of this guy!
//id <ColorLineDelegate> delegate;
}
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
#end
.m:
#import "ColorLine.h"
#implementation ColorLine
#synthesize delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
#end
Perhaps a bit late but to be "ARC compliant", you simply have to replace
#property (nonatomic, assign) id <ColorLineDelegate> delegate;
by
#property (nonatomic, strong) id <ColorLineDelegate> delegate;
Bye.
If you want a weak property, this also works.
#interface MyClass : NSObject {
__weak id <MyClassDelegate> _delegate;
}
#property (nonatomic, weak) id <MyClassDelegate> delegate;
you can also use
#dynamic delegate
in the implementation instead of synthesize.
hey guys,
i'm new to objective-c and i'm having trouble with the memory management. i declared 3 classes, Table, Dataset and my Main class. In my mainclass, i created an Dataset Object and now im trying to pass this Object over to a Tableobject, where i want to store it permanently. but it seems to me that the garbage collector kills the reference before i can use it.
heres some code:
Dataset:
//Dataset.h
#interface Dataset : NSObject {
NSMutableArray* daten;
}
#end
//Dataset.m
#import "Dataset.h"
#import "Datensatz.h"
#implementation Dataset
- (id) init
{
self=[super init];
daten=[[NSMutableArray alloc] init];
return self;
}
Table:
//Table.h
#class Dataset;
#interface Table : NSObject {
Dataset* daten;
}
-(id)init:(NSTableView *)aTableView;
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView;
#property (retain) Dataset* daten;
#end
//Table.m
#import "Table.h"
#import "Dataset.h"
#impl
ementation Table
#synthesize daten;
-(id)init:(NSTableView*)aTableView
{
self=[super init];
[self setDaten:[Datenmenge alloc]];
return self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
{
NSLog(#"anzahl: %d %#",[self.daten anzahl], self.daten);//This is always 0 null
return [daten anzahl];
}
-(void)setDaten:(Dataset *)a
{
NSLog(#"setter: anzahl: %d %#",[a anzahl], a);
[daten release];
daten=[a retain];
NSLog(#"setter: anzahl: %d %#",[daten anzahl], daten);
}
#end
In my mainclass i do the following:
//init method
[self setDaten:[[[Dataset alloc]init]autorelease]];
tabelle=[[Table alloc] init:tableview];
[tabelle setDaten:[self daten]];
Mainclass:
//code.h
//
// MalWiederWasNeuesAppDelegate.h
// MalWiederWasNeues
//
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#class Datenmenge,Graph,Tabelle;
#interface MalWiederWasNeuesAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
NSToolbarItem *datenKnopf;
NSToolbarItem *speichernKnopf;
NSSlider *scaleSlider;
NSScroller *moveSlider;
NSTableView* tableview;
Graph* graph;
Tabelle* tabelle;
Datenmenge* daten;
}
-(void)tuWas;
- (IBAction)datenHinzufuegen:(id)sender;
- (IBAction)speichern:(id)sender;
#property (assign) IBOutlet NSWindow *window;
#property (assign) IBOutlet NSToolbarItem *datenKnopf;
#property (assign) IBOutlet NSToolbarItem *speichernKnopf;
#property (assign) IBOutlet NSSlider *scaleSlider;
#property (assign) IBOutlet NSScroller *moveSlider;
#property (assign) IBOutlet Graph *graph;
#property (assign) IBOutlet Tabelle *tabelle;
#property (assign) IBOutlet NSTableView* tableview;
#property (retain) Datenmenge* daten;
#end
//code.m
//
// MalWiederWasNeuesAppDelegate.m
// MalWiederWasNeues
//
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "MalWiederWasNeuesAppDelegate.h"
#import "Datenmenge.h"
#import "Graph.h"
#import "Tabelle.h"
#implementation MalWiederWasNeuesAppDelegate
#synthesize window;
#synthesize daten;
-(id) init
{
self.daten=[[Datenmenge alloc]init];
[self.daten datenHinzufuegen:nil];
tabelle=[[Tabelle alloc] init:tableview];
tabelle.daten=daten;
NSLog(#"konstruktor: %f %d",[daten maximum],[daten anzahl]);
//graph.daten=daten;
return self;
}
-(void)tuWas{
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (IBAction)datenHinzufuegen:(id)sender
{
NSLog(#"%f %d",[daten maximum],[daten anzahl]);
NSLog(#"daten hinzufügen");
}
- (IBAction) speichern:(id)sender
{
NSLog(#"%# %#",daten,[tabelle daten]);
NSLog(#"speichern");
}
#end
I hope this wasnt too much code for you.
when i call a method of "tabelle", my Table object, "daten" does not refer to an Dataset Object. But the NSLogs in "setDaten" show me valid references.
so, what am i doing wrong?
have a good evening,
lukas
You define Daten as a retain type
#property (retain) Dataset* daten; and #synthesize daten;
theres no need to then implement the method
-(void)setDaten:(Dataset *)a thats what #synthesize daten; does
I think theres a lost in translation moment here so ill assume Table == Tabelle and Dataset == Datmenge and I dont see the implementation for your main class.
cast your eye over this too.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
Maybe, the daten property of your main class is declared as assign? In that case daten is correct when you call setDaten:, but might have been already autoreleased when you try to access it afterwards.
Also,
-(void)setDaten:(Dataset *)a
{
NSLog(#"setter: anzahl: %d %#",[a anzahl], a);
[daten release];
daten=[a retain];
NSLog(#"setter: anzahl: %d %#",[daten anzahl], daten);
}
is not a good implementation of a setter. If a == daten, then this object will be released (and maybe dealloc'd). You need to check identity of objects when implementing your own setter.