NSMutableArray* annotations = [[NSMutableArray alloc] init];
//This is the details needed to make a new annotation.
CLLocationCoordinate2D autoCoord1;
autoCoord1.latitude = 37.78616;
autoCoord1.longitude = -122.41018;
MyAnnotation* autoAnnot1 = [[MyAnnotation alloc] init];
autoAnnot1.coordinate = autoCoord1;
autoAnnot1.title = #"auto";
autoAnnot1.subtitle = #"auto";
[mapViewVC addAnnotation:autoAnnot1];
[annotations addObject:autoAnnot1];
I have this code that worked in another one of my mapkit apps, however I cannot seem to get an annotation autoAnnot1 to be seen on the map at the coordinates given.
Surely the code [mapViewVC addAnnotation:autoAnnot1];should add that annotation to the map?
MyAnnotation.h class looks like the following:
#import <Foundation/Foundation.h>
#import "MapKit/MapKit.h"
#interface MyAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString* title;
NSString* subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString* title;
#property (nonatomic, copy) NSString* subtitle;
#end
Below is an image showing the breakpoint and the output
I'm guessing the code you have shown us is in an initialiser method of a view controller. At this point, the view objects have not yet been instantiated. Your outlets are all nil. Code that sets up a view should go in the viewDidLoad method, which is called after the view has loaded and your outlets have been hooked up.
Related
I am trying to make a TableViewController.. I got it to work using code from a youtube lesson: "Cocoa Programming L13-14" But then when I try to change it so that the default values aren't hard coded... but rather the values of controls in the Interface Builder, I get (null) across the board. Here is the code:
#import <Foundation/Foundation.h>
#interface Person : NSObject {
IBOutlet NSPathControl* pcSource;
IBOutlet NSPathControl* pcDestination;
IBOutlet NSTextField* tfBackupAmount;
NSURL* urlSource;
NSURL* urlDestination;
NSString* strBackupAmount;
//Old--
//NSString* name;
//int age;
}
#property NSURL* urlSource;
#property NSURL* urlDestination;
#property NSString* strBackupAmount;
//Old--
//#property (copy) NSString* name;
//#property int age;
#end
and
#import "Person.h"
#implementation Person
#synthesize urlSource;
#synthesize urlDestination;
#synthesize strBackupAmount;
//Old--
//#synthesize name;
//#synthesize age;
- (id)init {
self = [super init];
if (self) {
urlSource = [pcSource URL];
urlDestination = [pcDestination URL];
strBackupAmount = [tfBackupAmount stringValue];
NSLog(#"%#\n%#\n%#",urlSource,urlDestination,strBackupAmount);
//Old--
//name = #"Yoda";
//age = 900;
//NSLog(#"%#: %i", name, age);
}
return self;
}
#end
Everything commented //Old-- worked, and interacted fine with the TableViewController. So I am assuming all that still works fine. The 3 controls (2 NSPathControl & 1 NSTextField) are linked up to an Object class:Person in Interface Builder with the controls linked up. Why am I getting output of:
(null)
(null)
(null)
? When I get to the NSLog(); line? Where am I going wrong?
Thanks!
pcSource, pcDestination, or tfBackupAmount aren't initialized when your init method is called, so they're all nil. Sending a message to nil is legal in Objective-C, and you'll just get nil back. That means urlSource, urlDestination, and strBackupAmount are all nil too, and that's why you ge the log output you're seeing.
You need to change the log message to sometime after those variables are initialized.
Try putting the code in -viewDidLoad rather than -init. It all has to do with the order of events (-init gets called before any of the IB stuff happens.
Ok, technically this question - I found an answer for it. It is to make a custom init method. In my case this means:
Person* p = [[Person alloc] initWithurlSource:[NSURL URLWithString:#"moo"] andurlDestination:[NSURL URLWithString:#"cow"] andstrBackupAmount:#"foo"];
However this still doesn't solve my problem of getting values for IBOutlets from another Class (in this case my TableViewController class) that has been exposed as #property:
#interface AppDelegate : NSObject <NSApplicationDelegate> {
.....
.....
#property (nonatomic, retain) NSPathControl* pcSource;
#property (nonatomic, retain) NSPathControl* pcDestination;
#property (nonatomic, retain) NSTextField* tfBackupAmount;
I am still having trouble getting values for these controls in my "addButtonPressed" method with:
//ad is AppDelegate - declared in interface as AppDelegate* ad;
NSPathControl* pcSource = [ad pcSource];
NSPathControl* pcDestination = [ad pcDestination];
NSTextField* tfBackupAmount = [ad tfBackupAmount];
This question already has an answer here:
How to make a property of a property
(1 answer)
Closed 9 years ago.
I want to have a result that looks like this player.type.property, An example of this is with UILabel, self.label.text. The .text being the property of the two classes.
A suggestion I have had is to do something like this:
player.type = [[MyCustomObject alloc] init];
player.type.property = #"value";
Although I'm not quite sure exactly how to go about doing this correctly, every method I have tried doesn't work.
Here is what I have tried:
Marketplace.h
#import "Item.h"
#interface Marketplace : NSObject
#property (nonatomic, assign) Item *market;
Item.h
#interface Item : NSObject
#property (nonatomic, assign) int price;
Starter.m
#import "Marketplace.h"
#import "Item.h"
#implementation MainGameDisplay
{
Marketplace *market;
Item *itemName;
}
-(void) executedMethod {
market.itemName = [[market alloc] init];
//2 errors: "Property 'itemName not found on object of type 'MarketPlace'" and "No visible #interface for 'MarketPlace' declares the selector alloc"
market.itemName.price = 5; //"Property 'itemName' not found on object of type 'Marketplace*'"
}
Each pointer to class object must be alloc init, so you need to over-write the -(id)init inside its class.
Item.h
#interface Item : NSObject
#property (nonatomic) NSInteger price;
Marketplace.h
#import "Item.h"
#interface Marketplace : NSObject
#property (nonatomic, strong) Item *item;//Item is a class, must use strong or retain
Marketplace.m
-(id)init{
if (self = [super init]) {
self.item = [[Item alloc] init];//Item must alloc together when MarcketPlace init
}
return self;
}
*Then you just init the Marketplace
#implementation MainGameDisplay
{
Marketplace *market;
Item *itemName;
}
-(void) executedMethod {
market = [Marketplace alloc] init];
//Now you can access
market.item.price = 5;
}
1 . make a Interface named PlayerType Put some property there and synthesize them.
2. now make a Interface named Player and import the PlayerType Interface there.
3. make a property of PlayerType Interface like #property(nonatomic, strong) PlayerType *type.
now made variable of Player it will allow you to access property of a property.
I recently started learning Objective-C and Cocos-2D. I tried to define my own method for automating the creation of sprites.
I added my own class where I'll create other automation methods as well. Anyhow my .h file looks like this:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#interface ActionsClass : CCNode {
}
#property (nonatomic, strong) CCSprite* createSprite;
#property (nonatomic, strong) CCSprite* spriteName;
#property (nonatomic, strong) NSString* pngName;
#property (nonatomic) CGPoint* spriteCoordinate;
- (CCSprite *)createSprite: (CCSprite *)spriteName: (NSString *)pngName: (CGPoint *)spriteCoordinate;
#end
And the .m is:
#import "ActionsClass.h"
#implementation ActionsClass
#synthesize createSprite = _createSprite;
#synthesize spriteName = _spriteName;
#synthesize pngName = _pngName;
#synthesize spriteCoordinate = _spriteCoordinate;
- (CCSprite *)createSprite: (CCSprite *)spriteName: (NSString *)pngName: (CGPoint *)spriteCoordinate
{
if (!_createSprite)
{
_createSprite = [[CCSprite alloc] init];
_spriteName = [CCSprite spriteWithFile:_pngName];
_spriteName.position = ccp(_spriteCoordinate->x, _spriteCoordinate->y);
[self addChild:_spriteName];
}
return _createSprite;
}
#end
In the main .m file where I want to call the method:
[self createSprite: saif: #"saif.png": ccp(100,100)];
This would give the warning that xcode didn't find the instance method createSprite and defaults it to id
Thanks a lot and sorry if the font or the formatting of the question aren't super neat.
Your method declaration is wrong, so you wont be able to call it.
It should be:
- (CCSprite *)createSprite:(CCSprite *)spriteName pngName:(NSString *)pngName coord:(CGPoint *)spriteCoordinate;
And called like:
[self createSprite:someSprite pngName:somePNGName coord:someCoord];
Edit: I didn't see that you were trying to call this from another class. To do that you will need to import the ActionsClass header file, and call this method on an instance of ActionsClass, e.g.
ActionsClass *actionsClassObject = [[ActionsClass alloc] init];
[actionsClassObject createSprite:someSprite pngName:somePNGName coord:someCoord];
Right before my model class sends the variable stringToDisplay, NSLog shows me that it has a value. But when I try to use it in my ViewController, I just get (null). Any thoughts about what I'm doing wrong?
(The good news is that, while working on this, I had sort of a breakthrough in understanding how models and controllers relate to each other. I'm still a complete newbie, but I don't feel quite as lost as I did.)
Here's what I think is the relevant code:
CalculatorBrain.h
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
#property (nonatomic) NSMutableString *stringToAdd;
#property (nonatomic,strong) NSString *stringForDisplay;
- (double)performOperation:(NSString *)operation withArray:(NSMutableArray *)particularStackYouNeedToPopOff;
CalculatorBrain.m
#implementation CalculatorBrain
#synthesize stringToAdd = _stringToAdd;
#synthesize stringForDisplay = _stringForDisplay;
#synthesize whatHappenedSinceLastClear = _whatHappenedSinceLastClear;
- (double)performOperation:(NSString *)operation withArray:(NSMutableArray *)particularStackYouNeedToPopOff
{
<long code that I think doesn't matter because this NSLog produces exactly what I want it to:>
NSLog(#"%#",stringForDisplay);
return result;
}
CalculatorViewController.h
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
#property (nonatomic) NSArray *arrayOfDictionaries;
#property (nonatomic) NSDictionary *dictionary;
#property (weak, nonatomic) IBOutlet UILabel *variablesUsed;
#property (nonatomic, strong) NSString *operation;
#end
CalculatorViewController.m
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
#interface CalculatorViewController ()
#property (nonatomic,strong) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize display = _display;
#synthesize history = _history;
#synthesize brain = _brain;
#synthesize operation = _operation;
- (IBAction)operationPressed:(UIButton *)sender
{
NSString *otherString=[self.brain stringForDisplay];
if (self.userIsEnteringNumber) [self enterPressed];
NSString *operation = sender.currentTitle;
double result = [self.brain performOperation:operation withArray:[self.brain whatHappenedSinceLastClear]];
self.display.text = [NSString stringWithFormat:#"%g",result];
self.history.text = otherString;
NSLog(#"%#",otherString);
}
And the NSLog in that last line of code give me (null).
Any thoughts?
Maybe I'm missing something but your property is declared in the class extension of CalculatorBrain so nobody outside CalculatorBrain.m knows about this property.
So if you want to expose this property to other objects, you will have to declare it in CalculatorBrain.h instead.
Oh - your declaration of the property whatHappenedSinceLastClear isn't exposed to other classes that import CalculatorBrain.h because you put the property declaration in an interface extension in the .m file, which other classes will not see.
To make it publicly accessible move the #property line for whatHappenedSinceLastClear to CalculatorBrain.h, not the .m file.
I can guess that problem lies in the way you assign your stringForDisplay, eg.:
if you use something like
stringForDisplay_ = anotherString;
setter for property doesn't fire, so you have to retain your variable yourself otherwise it'll live just until your method finishes;
If so - use property setters, eg.:
self.stringForDisplay = anotherString;
that way ARC will do all the memory management.
It really depends how you set stringForDisplay inside the performOperation:withArray: method.
for a blind guess, try using
NSString *otherString = self.brain.stringForDisplay;
after this line
double result = [self.brain performOperation:operation withArray:[self.brain whatHappenedSinceLastClear]];
I have a subclass of UITableViewController, and I init the subclass with a NSMutableArray of another custom class:
#import <UIKit/UIKit.h>
#import "NUBCheckpointModel.h"
#interface NUBUserCheckpointModel : NSObject
#property (nonatomic,assign) NSString* objId;
#property (nonatomic,assign) NSString* userId;
#property (nonatomic,assign) NSString* checkpointId;
#property (nonatomic,assign) NSDate* dateAdded;
#property (nonatomic,assign) NUBCheckpointModel* checkpoint;
+ (NUBUserCheckpointModel*) fromJson: (NSString*)json;
#end
This array that is generated from another ViewController, gets passed into this subclassed TableViewController, of which contain this property
#property (nonatomic,retain) NSMutableArray* userCheckpointData;
This property is set like this:
- (id)initWithFrame: (CGRect)frame withType: (TableType)typeOfTable fromParent: (UIViewController*)parent data: (NSMutableArray*)ucpData
{
self = [self init];
if (self) {
self.tableView = [[UITableView alloc] initWithFrame:frame];
self.parentController = parent;
self.userCheckpointData = ucpData;
[self styleTable];
[self addPullToRefreshHeader];
typeCategory = typeOfTable;
}
return self;
}
All is fine up to this part, and any manipulation including trying to get an object from the array works fine. I tested it.
The code I used to test the array is:
NUBUserCheckpointModel* model = [self.userCheckpointData objectAtIndex:0];
NSLog(model.objId);
However, this very same code, when used here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Gives me exc_bad_access. May I know why this happens? I can't seem to figure out why. I'm using ARC btw. Thank you.
While adding the property, you need to take care of the memory management. For string, it is not good practice to set assign property.
Instead , do as following,
#property (nonatomic,copy) NSString* objId;
#property (nonatomic,copy) NSString* userId;
#property (nonatomic,copy) NSString* checkpointId;
#property (nonatomic,retain) NSDate* dateAdded;
#property (nonatomic,retain) NUBCheckpointModel* checkpoint;