Im learning Objective-C and im having some problems with a project.
I made a class with a method to create a new object and im having some issues trying to create a new Object, i dont know what is the best kind of proporties in this case.
Class.h
#import <Foundation/Foundation.h>
#interface ObrasData : NSObject
#property (strong) NSNumber *ID;
#property (assign) char presupuesto;
#property (assign) char descripcion;
#property (assign) char aasm_state;
#property (assign) char clienteID;
- (id)initWithID:(NSNumber*)ID presupuesto:(char)presupuesto description:(char)description aasm_state:(char)aasm_state clienteID:(char)clienteID;
#end
Class.m
#implementation ObrasData
#synthesize ID = _ID;
#synthesize presupuesto = _presupuesto;
#synthesize descripcion = _descripcion;
#synthesize aasm_state = _aasm_state;
#synthesize clienteID = _clienteID;
- (id)initWithID:(NSNumber *)ID presupuesto:(char)presupuesto description:(char)description aasm_state:(char)aasm_state clienteID:(char)clienteID{
if ((self = [super init])) {
self.ID = ID;
self.presupuesto = presupuesto;
self.descripcion = description;
self.aasm_state = aasm_state;
self.clienteID = clienteID;
}
return self;
}
And here im having the error: "Incompatible pointer to integer conversion"
ObrasData *obra1 = [[ObrasData alloc] initWithID:[NSNumber numberWithInt:1] presupuesto:100 description:#"obra de prueba" aasm_state:#"En proceso" clienteID:#"dm2"];
What im doing wrong? I want to show later the object on a listview
Class.h
#import <Foundation/Foundation.h>
#interface ObrasData : NSObject
#property (strong) NSNumber *ID;
#property (strong) NSString *presupuesto;
#property (strong) NSString *descripcion;
#property (strong) NSString *aasm_state;
#property (strong) NSString *clienteID;
- (id)initWithID:(NSNumber*)ID presupuesto:(NSString *)presupuesto description:(NSString *)description aasm_state:(NSString *)aasm_state clienteID:(NSString *)clienteID;
#end
Class.m
#implementation ObrasData
#synthesize ID = _ID;
#synthesize presupuesto = _presupuesto;
#synthesize descripcion = _descripcion;
#synthesize aasm_state = _aasm_state;
#synthesize clienteID = _clienteID;
- (id)initWithID:(NSNumber *)ID presupuesto:(NSString *)presupuesto description:(NSString *)description aasm_state:(NSString *)aasm_state clienteID:(NSString *)clienteID{
if ((self = [super init])) {
self.ID = ID;
self.presupuesto = presupuesto;
self.descripcion = description;
self.aasm_state = aasm_state;
self.clienteID = clienteID;
}
return self;
}
and call like this :
ObrasData *obra1 = [[ObrasData alloc] initWithID:[NSNumber numberWithInt:1] presupuesto:#"100" description:#"obra de prueba" aasm_state:#"En proceso" clienteID:#"dm2"];
In initWithID method second parameter input type is char but you are passing integer 100.
[[ObrasData alloc] initWithID:[NSNumber numberWithInt:1] presupuesto:100 description:#"obra de prueba" aasm_state:#"En proceso" clienteID:#"dm2"];
change presupuesto to Char
Related
I have good Setter and Getter code for Object. How do same for BOOL using objc/runtime.h like here?
objc_getAssociatedObject require object
.h
#import <Foundation/Foundation.h>
#interface UITableView (Additions)
#property (nonatomic, retain) NSNumber *allowReplenishment;
#end
.m
#import "UITableView+Additions.h"
#import <objc/runtime.h>
#implementation UITableView (Additions)
- (NSNumber *)allowReplenishment {
return objc_getAssociatedObject(self, #selector(allowReplenishment));
}
- (void)setAllowReplenishment:(NSNumber *)value {
objc_setAssociatedObject(self, #selector(allowReplenishment), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
If you want to declare your bool property
#property (nonatomic, assign) BOOL isAllowReplenishment, just create the object in the setter instead, as needed:
- (void)setIsAllowReplenishment:(BOOL)isAllowReplenishment
{
NSNumber *isBool = [NSNumber numberWithBool:isAllowReplenishment];
objc_setAssociatedObject(self, #selector(isAllowReplenishment), isBool, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isAllowReplenishment
{
NSNumber *isBool = objc_getAssociatedObject(self, #selector(isAllowReplenishment));
return isBool.boolValue;
}
I have an 2 objective C classes:
Class 1 scanDatabase (Scans a database and puts that into a mutable array)
Class 2 Mapper (Is a mapping class for the database scan "model")
In objective C this successfully scans the database and puts it into a mutable array. Using the mapping class I can access individual groups of elements (AlbumTitles) like so:
for (Mapper *mapper in scanResult) {
NSLog(#"%#", mapper.AlbumTitle);
}
Everything is working as it should and I can return individual elements from my array i.e as above I am only returning album titles.
I then need to use that array in Swift. I call the objective C in my Swift class and again it runs fine and creates the array. This is done with:
let scanTable = ScanTable();
let scanMapper = Mapper();
scanTable.scanTableDo();
but when I try to retrieve a particular set of items like Album title as I did in the objective C for loop above I get the error "scanMapper is not a type" (scanMapper is my swift instance of the objective C mapper class:
I tried two different ways and both have the same error:
for mapper: scanMapper in scanTable.scanResult {
print("\(mapper.AlbumTitle)")
}
for object in scanTable.scanResult as! [scanMapper] {
print("\(mapper.AlbumTitle)")
}
Can I use an objective C class as a model/mapper and not sure whether I would need to recreate it in Swift.
I will include the mapper and scanTable .h and .m code just in case it is needed, plus the bridging header:
Mapper.h:
#import <Foundation/Foundation.h>
#import <AWSDynamoDB/AWSDynamoDB.h>
#interface Mapper : AWSDynamoDBObjectModel <AWSDynamoDBModeling>
#property (nonatomic, strong) NSNumber *SongID;
#property (nonatomic, strong) NSString *Artist;
#property (nonatomic, strong) NSString *SongURL;
#property (nonatomic, strong) NSString *Location;
#property (nonatomic, strong) NSNumber *UserRatings;
#property (nonatomic, strong) NSNumber *AVGUserRating;
#property (nonatomic, strong) NSString *Category;
#property (nonatomic, strong) NSString *PictureURL;
#property (nonatomic, strong) NSNumber *SongDuration;
#property (nonatomic, strong) NSString *SongTitle;
#property (nonatomic, strong) NSNumber *AVGMusicianRating;
#property (nonatomic, strong) NSString *AlbumTitle;
#end
Mapper.m
#import <AWSDynamoDB/AWSDynamoDB.h>
#import "Mapper.h"
#implementation Mapper
+ (NSString *)dynamoDBTableName {
return #"Songs";
}
+ (NSString *)hashKeyAttribute {
return #"SongID";
}
#end
ScanTable.h:
#import <Foundation/Foundation.h>
#import <AWSDynamoDB/AWSDynamoDB.h>
#interface ScanTable : NSObject
- (void) scanTableDo;
#property (nonatomic, strong) NSMutableArray *scanResult;
#end
ScanTable.m
#import "ScanTable.h"
#import "Mapper.h"
#implementation ScanTable
- (void) scanTableDo {
AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper];
AWSDynamoDBScanExpression *scanExpression = [AWSDynamoDBScanExpression new];
scanExpression.limit = #10;
[[dynamoDBObjectMapper scan:[Mapper class]
expression:scanExpression]
continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(#"The request failed. Error: [%#]", task.error);
}
if (task.exception) {
NSLog(#"The request failed. Exception: [%#]", task.exception);
}
if (task.result) {
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
NSMutableArray *scanResult = [[NSMutableArray alloc] initWithArray:paginatedOutput.items]; //// ADDED /////
for (Mapper *mapper in scanResult) {
NSLog(#"%#", mapper.AlbumTitle);
}
}
return nil;
}];
}
#end
//EDITED ADDED BRIDGING HEADER//
MySampleApp-Bridging-Header.h:
//
// MySampleApp-Bridging-Header.h
// MySampleApp
#import "ScanTable.h"
#import "Mapper.h"
#import "Hello World.h"
Thanks for your help
The problem is just as the error explains, you're attempting to cast the items in your array to scanMapper, which is a variable holding an instance of Mapper, not the Mapper type itself. Assuming that scanTable.scanResult is an NSArray of Mappers, try this instead:
guard let scanResult = scanTable.scanResult as? [Mapper] else {
print("scanResult was not an array of mappers!")
return
}
for mapper: Mapper in scanResult {
print("\(mapper.AlbumTitle)")
}
Suppose I have a simple DTO class like this:
#interface MYNugget
#property (nonatomic, copy) NSString *color;
#end
#implementation MYNugget
// automatic #synthesize
#end
And I then later want to store this object in another class in a way such that it is not modifiable (that is, make the color property readonly via a - (void)freeze or something.
What is the best way to accomplish this short of writing my own setters?
The standard way is to have to classes, one mutable and an immutable one.
#interface MYNugget
#property (nonatomic, copy, readonly) NSString *color;
#end
and
#interface MYMutableNugget : MYNugget
#property (nonatomic, copy, readwrite) NSString *color;
#end
Your other class would just expose a MYNugget property, ideally again as copy. That's how we do it with NSString all the time.
What I would do is set the color via the constructor only:
#interface MYNugget
#property (nonatomic, copy, readonly) NSString *color;
- (id) initWithColor:(NSString *)color;
#end
#implementation MYNugget
#synthesize color = _color;
- (id) initWithColor:(NSString *)color {
self = [super init];
if (self) {
_color = [color copy];
}
return self;
}
#end
I run this code:
- (void)unitButtonButtonTapped:(id)sender {
[_label setString:#"Last button: Unembossed square"];
MilitaryUnits *target = nil;
target = [Peasants militaryUnits];
target.position = ccp(100, 450);
[self addChild:target];
}
And I get this error:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Argument must be non-nil'
These are my .h and .m class files
#import "cocos2d.h"
#interface MilitaryUnits : CCSprite {
int _experience;
int _number_of_units;
int _stamina;
int _armor_level;
int _weapon_levell;
}
#property (nonatomic, assign) int experience;
#property (nonatomic, assign) int number_of_units;
#property (nonatomic, assign) int stamina;
#property (nonatomic, assign) int armor_level;
#property (nonatomic, assign) int weapon_levell;
#end
#interface Peasants : MilitaryUnits{
}
+(id)militaryUnits;
#end
#import "MilitaryUnits.h"
#implementation MilitaryUnits
#synthesize number_of_units = _number_of_units;
#synthesize stamina = _stamina;
#synthesize experience = _experience;
#synthesize armor_level = _armor_level;
#synthesize weapon_levell = _weapon_levell;
#end
#implementation Peasants
+ (id)militaryUnits {
Peasants *militaryUnits = nil;
if ((militaryUnits = [[[super alloc] initWithFile:#"Target.png"] autorelease])) {
}
return militaryUnits;
}
#end
Note, I'm using cocos 2d
looks to me like your sprite is nil, ie the file "Target.png" is not found. Make certain the file name has the same case (in finder) as you spelled out in your code, and that the file is included in the target's membership in Xcode.
Also
+ (id)militaryUnits {
Peasants *militaryUnits;
if ((militaryUnits = [[[super alloc] initWithFile:#"Target.png"] autorelease])) {
return militaryUnis;
} else {
CCLOGERROR(#"your favorite whine style for errors like file not found");
return nil;
}
}
Currently I’m trying to get the hang of a block copy with my current project. The structure of the copy is an NSMutableArray that contains NSIntegers, NSStrings another NSMutableArray and two Objects… Those objects in turn hold NSStrings. The Array contains Objects which hold an NSInteger and Two Objects which contain strings…
I believe I am supposed to use the Block Copy method for coping objects… Code is below…
I am aware the code is not releasing properly… I tried to make the code smaller for your benefit.
Any insight you could shed would be awesome.
//Main controller Excerpt
//Insert Position Information into temporary node point... Node Points can have multiple Positions (or rather you can face multiple directions at the node. Each Node has 3-4 of these.
[newNode.positionArray insertObject:[newPosition copy] atIndex:currentPosition];
Insert the temporary node into the Node Array.
[nodeArray insertObject:[newNode copy] atIndex:count];
//Main Controller Excerpt
//
// Node.h
//
#import <Foundation/Foundation.h>
#class Sequence;
#class Position;
#interface Node : NSObject {
NSInteger Id;
NSInteger currentPosition;
NSString *title;
NSMutableArray *positionArray;
Sequence *forwardSequence;
Sequence *backSequence;
}
-(id) copyWithZone: (NSZone *) zone;
#property (nonatomic, assign) NSInteger Id;
#property (nonatomic, assign) NSInteger currentPosition;
#property (nonatomic, assign) NSString *title;
#property (nonatomic, retain) NSMutableArray *positionArray;
#property (nonatomic, retain) Sequence *forwardSequence;
#property (nonatomic, retain) Sequence *backSequence;
#end
//
// Node.m
//
#import "Sequence.h"
#import "Position.h"
#import "Node.h"
#implementation Node
#synthesize Id;
#synthesize currentPosition;
#synthesize positionArray;
#synthesize title;
#synthesize forwardSequence;
#synthesize backSequence;
-(id) copyWithZone: (NSZone *) zone {
Node *nodeCopy = [[Node allocWithZone: zone] init];
nodeCopy.Id = Id;
nodeCopy.currentPosition = currentPosition;
nodeCopy.positionArray = [positionArray copy];
nodeCopy.title = title;
nodeCopy.forwardSequence = [forwardSequence copy];
nodeCopy.backSequence = [backSequence copy];
return nodeCopy;
}
#end
//
// Position.h
//
#import <Foundation/Foundation.h>
#class Sequence;
#interface Position : NSObject <NSCopying> {
NSInteger Id;
Sequence *leftSequence;
Sequence *rightSequence;
}
#property (nonatomic, assign) NSInteger Id;
#property (nonatomic, retain) Sequence *leftSequence;
#property (nonatomic, retain) Sequence *rightSequence;
-(id) copyWithZone: (NSZone *) zone;
#end
//
// Position.m
//
#import "Sequence.h"
#import "Position.h"
#implementation Position
#synthesize Id;
#synthesize leftSequence;
#synthesize rightSequence;
-(id) copyWithZone: (NSZone *) zone {
Position *positionCopy = [[Position allocWithZone: zone] init];
positionCopy.Id = Id;
positionCopy.leftSequence = [leftSequence copy];
positionCopy.rightSequence = [rightSequence copy];
return positionCopy;
}
#end
//
// Sequence.h
//
#import <Foundation/Foundation.h>
#interface Sequence : NSObject <NSCopying> {
NSInteger numberOfFrames;
NSString *imageNameScheme;
NSString *endFrame;
}
-(id) copyWithZone: (NSZone *) zone;
#property (nonatomic, assign) NSInteger numberOfFrames;
#property (nonatomic, copy) NSString *imageNameScheme;
#property (nonatomic, copy) NSString *endFrame;
#end
//
// Sequence.m
// MCIT
//
#import "Sequence.h"
#implementation Sequence
#synthesize numberOfFrames;
#synthesize imageNameScheme;
#synthesize endFrame;
-(id) copyWithZone: (NSZone *) zone {
Sequence *sequenceCopy = [[Sequence allocWithZone: zone] init];
sequenceCopy.numberOfFrames = numberOfFrames;
sequenceCopy.imageNameScheme = imageNameScheme;
sequenceCopy.endFrame = endFrame;
return sequenceCopy;
}
#end
Works like a charm now thanks all. :D
If your intent is to make this a copyable class, then you need to declare that it conforms to the NSCopying protocol like so:
#interface Node: NSObject <NSCopying> {
Falling to declare the protocol can cause other objects to believe that the class is uncopyable even if it has a copyWithZone: method.