Getting incompatible integer to pointer error - objective-c

Im getting the error incompatible integer to pointer conversion returning unsigned int from a function with result type NSUInteger *
I'm not sure what is that mean since they are kind of the same, no..? sorry im totally a newbie, here is my code for my PlayingCards deck class:
PlayingCards.h
#import "Card.h"
#interface PlayingCards : Card
#property (strong, nonatomic) NSString *suit;
#property (nonatomic) NSUInteger rank;
+(NSArray *) validSuit;
+(NSUInteger *) maxRank;
#end
PlayingCards.m
#import "PlayingCards.h"
#implementation PlayingCards
#synthesize suit = _suit;
//modifying the contents getter so it will return array with the ranks and rank+suit
-(NSString *) contents {
NSArray *cardsRank = [PlayingCards rankStrings];
return [cardsRank[self.rank] stringByAppendingString:self.suit];
}
//creating a method to make sure we get validated suits
+(NSArray *) validSuit {
return #[#"♠",#"♣",#"♥",#"♦"];
}
//creating calss method to validate the rank
+(NSArray *) rankStrings {
return #[#"?",#"A",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"J",#"Q",#"K"];
}
//creating a new setter for suit to make sure we get the valitated suits, uding the validateSuit method
-(void) setSuit:(NSString *)suit {
if ([[PlayingCards validSuit] containsObject:suit]) {
_suit = suit;
}
}
//creating new getter for suit to make sure its not empty
-(NSString *) suit {
return _suit? _suit: #"?";
}
//creating a class method to make sure when user set the rank he will will
+(NSUInteger *) maxRank {
return [self rankStrings].count - 1;
}
//creating a new setter to the renk to make sure the rank is validates
-(void) setRank:(NSUInteger)rank {
if (rank <= [PlayingCards maxRank]) {
_rank = rank;
}
}
#end
please help me to figure this out, its in the line (in the .m file):
+(NSUInteger *) maxRank {
return [self rankStrings].count - 1;
}
And effecting on the line:
-(void) setRank:(NSUInteger)rank {
if (rank <= [PlayingCards maxRank]) {
_rank = rank;
}
}
With another error
order comparison between pointer and integer
thanks!

This usually means you have tried to accidentally use a pointer where you should not. Or didn't use a pointer where you should have.
Your class method is returning a pointer to your NSUInteger. Remove the *

Related

Why does the object in this Objective C code not set?

I have the below code which simply read a bunch of cards and inputs their names into a Mutable Array if they are not present beforehand.
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSMutableArray *allCards = [[NSMutableArray alloc] init];
char cardAvailable = '\0';
do {
Card *newCard = [[Card alloc] init];
NSLog(#"What is the Card Name ?\n");
char cName[20];
scanf("%s",cName);
NSString *nName = [NSString stringWithCString:cName encoding:1];
[newCard setName:nName];
if([newCard wasMatch:allCards]) {
NSLog(#"Card Already Present");
} else {
NSLog(#" NEW CARD NAME %# %# %s",[newCard getName],newCard.name, cName);
[newCard addGlobal:newCard toArray:allCards];
}
NSLog(#"Is there another Card to Input?");
scanf("%c",&cardAvailable);
} while(cardAvailable != 'N' || cardAvailable != 'n');
NSLog(#":::: Card Names Are ::::");
for(Card *card in allCards)
{
NSLog(#"%#",card.name);
}
}
return 0;
}
However, first - The name is simply NOT SET. I don't know why this is happening. Today was my first day ever with Objective C, so please pardon me if this is too simple.
The Card class files are -
#import <Foundation/Foundation.h>
#interface Card : NSObject
#property(nonatomic) BOOL chosen;
#property (nonatomic, getter = getName) NSString *name;
-(BOOL)wasMatch:(NSMutableArray*) allCards;
-(void)addGlobal:(Card*) aCardName toArray:(NSMutableArray*) allCards;
-(void)setName:(NSString *)name;
-(void)setChosen:(BOOL)chosen;
#end
I get the error here - in the add global line.
#import "Card.h"
#implementation Card
#synthesize chosen = _chosen;
-(BOOL)chosen
{
return _chosen;
}
-(void)setChosen:(BOOL)chosen
{
_chosen = chosen;
}
#synthesize name = _name;
-(NSString*)getName
{
return _name;
}
-(void)setName:(NSString*)name
{
name = _name;
}
-(BOOL)wasMatch:(NSMutableArray *)allCards
{
for(Card *card in allCards)
{
if([self.name isEqualToString:card.name])
{
return true;
}
}
return false;
}
-(void)addGlobal:(Card *)aCardName toArray:(NSMutableArray *)allCards
{ NSLog(#" THE NS STRING %#",aCardName.name);
[allCards addObject:aCardName.name];
}
#end
Your setter is wrong.
-(void)setName:(NSString*)name
{
name = _name;
}
You assign the current instance variable (_name) to the parameter.
This should be the other way around.
-(void)setName:(NSString*)name
{
_name = name;
}
But you don't need this at all. There are various problems with your code.
Objective-C does not use getFoo for ordinary getters.
#property (nonatomic, getter = getName) NSString *name; should be
#property (copy, nonatomic) NSString *name;
And unless you are writing code in a ancient version of Objective-C (which you shouldn't) you don't need explicit getters and setters. In recent version you don't even have to explicitly synthesize.
In newer version of Objective-C your Card class should look more like this:
#interface Card : NSObject
#property (assign, nonatomic) BOOL chosen;
#property (copy, nonatomic) NSString *name;
-(BOOL)wasMatch:(NSMutableArray*) allCards;
-(void)addGlobal:(Card*) aCardName toArray:(NSMutableArray*) allCards;
#end
#import "Card.h"
#implementation Card
-(BOOL)wasMatch:(NSMutableArray *)allCards
{
for(Card *card in allCards)
{
if([self.name isEqualToString:card.name])
{
return YES;
}
}
return NO;
}
-(void)addGlobal:(Card *)aCardName toArray:(NSMutableArray *)allCards
{ NSLog(#" THE NS STRING %#",aCardName.name);
[allCards addObject:aCardName.name];
}
#end
Way less code. You might want to look for a more up to date learning resource.
The rest of your code looks questionable as well. I honestly don't see the point in addGlobal:toArray:. But I don't want to make this answer longer than necessary. ;-)
Also, for the love of your future self, don't use 1 in NSString *nName = [NSString stringWithCString:cName encoding:1]; use the constant. In your case NSASCIIStringEncoding. But because it's no longer 1980 you most likely want to use NSUTF8StringEncoding instead of ASCII.
As I said, please get more recent and decent learning resources.
In the -setName: property accessor method, you assign the the _name instance variable value to the name parameter. It should be swapped like this:
-(void)setName:(NSString*)name
{
_name = name;
}
To learn Objective-C i reccomment the most recent Stanford lectures by Paul Hegarty. CS193p the class is called. You can find all materials, and excellent videos on iTunes U. Other then Apple resource, there is no better then this.

iOS Store random property in Component e.g. UITextField without Subclass

Does anyone know if there is a way to set a property like a string in the User Defined Runtime Atributes sections of Interface Builder without creating a subclass of said component? For example, I want to store a metadata value for each component in my interface that I use later. I just don't want to have to create a subclass or each component to add a metadata property.
This is one approach I came up with. Opinions?
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#interface UIControl(MetaData)
#property (nonatomic, retain) id entityProperty;
#end
#implementation UIControl(MetaData)
static char const * const EntityPropertyKey = "EntityProperty";
#dynamic entityProperty;
- (id)entityProperty {
return objc_getAssociatedObject(self, EntityPropertyKey);
}
- (void)setEntityProperty:(id)newEntityProperty {
objc_setAssociatedObject(self, EntityPropertyKey, newEntityProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
...
if (textField.entityProperty)
[managedObject setValue: textField.text forKey:textField.entityProperty];
You could keep an NSDictionary somewhere, perhaps in a singleton object that has methods for issuing unique ids for objects and storing metadata by the id keys in the dictionary. The UI objects have a tag property that you can use, if your ids are just incremented integers. Then the dictionary keys would just be NSNumbers for those unique integers.
Like this:
#import <Foundation/Foundation.h>
#interface ACLMetadataManager : NSArray
+(ACLMetadataManager*) sharedMetadataManager;
-(NSUInteger) getUniqueId;
-(void) setObject: (id) object forId:(NSUInteger) theId;
-(id) objectForId:(NSUInteger) theId;
#end
And:
#import "ACLMetadataManager.h"
#implementation ACLMetadataManager { // Private variables
NSMutableDictionary *_metadata;
NSUInteger _ids;
}
- (id)init {
self = [super init];
if (self) {
_metadata = [[NSMutableDictionary alloc] init];
}
return self;
}
+(ACLMetadataManager*) sharedMetadataManager { // Singleton getter
static ACLMetadataManager *instance;
if (instance != nil) {
return instance;
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
static dispatch_once_t oneTimeThread;
dispatch_once(&oneTimeThread, ^(void) {
instance = [[ACLMetadataManager alloc] init];
});
#else
#synchronized(self) {
instance = [[ACLMetadataManager alloc] init];
}
#endif
return instance;
}
-(NSUInteger) getUniqueId { // Increment unique id when getter is called.
return ++_ids; // Start from 1 because tag is 0 by default.
}
-(void) setObject: (id) object forId:(NSUInteger) theId {
[_metadata setObject:object forKey:[NSNumber numberWithInteger:theId]];
}
-(id) objectForId:(NSUInteger) theId {
return [_metadata objectForKey:[NSNumber numberWithInteger:theId]];
}
// Override some methods to ensure singleton stays instantiated.
- (id) retain {
return self;
}
- (oneway void) release {
// Does nothing here.
}
- (id) autorelease {
return self;
}
- (NSUInteger) retainCount {
return INT32_MAX;
}
#end
Usage:
ACLMetadataManager *metadataManager = [ACLMetadataManager sharedMetadataManager];
myControl.tag = [metadataManager getUniqueId];
[metadataManager setObject:myMetadata forId:myControl.tag];

how to move an object from one array to another

I understand that this topic has been done before but I wanted to bring it up again for a specific reason, I have a function designed to move an item from one array to another, removing the item from the array it was originally in, but whenever I test it, it doesnt seem to work
-(void) moveOpperand: (NSMutableArray *) moveFrom :(NSMutableArray *) moveTo{
NSString *opperandObject = [moveFrom lastObject];
if (opperandObject) {
[moveTo addObject:moveFrom.lastObject];
[moveFrom removeLastObject];
}
}
the method above is called in this method
-(NSMutableArray *) giveHand: (NSMutableArray *) hand : (NSMutableArray *)refrenceDeck{
for (int i=0; i<6; i++) {
[self moveOpperand:refrenceDeck :hand];
}
return hand;
}
the error when testing seems to be located when I try to implement the currentHand method
-(NSMutableArray *) currentHand{
if (_currentHand == nil) {
self.currentHand = [self.myDeck giveHand:self.currentHand :self.myDeck.currentDeck];
}
return _currentHand;
}
If you're trying to do what I think here is a very very simple category that should do it for any object.
NSObject+Move.h
#import <Foundation/Foundation.h>
#interface NSObject (Move)
/*
Returns true if it sucessfully moves the object between arrays.
*/
- (BOOL)moveFromArray:(NSMutableArray *)arrayA toArray:(NSMutableArray *)arrayB;
#end
NSObject+Move.m
#import "NSObject+Move.h"
#implementation NSObject (Move)
- (BOOL)moveFromArray:(NSMutableArray *)arrayA toArray:(NSMutableArray *)arrayB
{
if ([arrayA containsObject:self]) {
[arrayA removeObject:self];
[arrayB addObject:self];
return YES;
} else {
return NO;
}
}
#end
It's possible that you aren't setting the _currentHand variable to nil at the appropriate time, thus you may not have the correct current hand which may make it 'seem' like an issue with your array swapping.

Request for member 'pData' with BOOL value TRUE is not a structure or union-Objective C

I could not use the pData[4096] to pass it to the other function from main.
data.m
------
#implementation data
static int msgID;
static char pData[4096]="\0";
+ (void)initialize
{
//some initialisations
msgID =123;
}
-(void)SwapEndian:(uint8_t*)pData withBOOLValue:(BOOL)bIsAlreadyLittleEndian
{
NSLog("%s %s",pData,bIsAlreadyLittleEndian);
}
#end
main.m
-------
[dat SwapEndian:dat.pData withBOOLValue:TRUE];
I am getting pData undeclared. As pData is declared as static inside the Data
implementation i tried with dat.pData to pass it from main.But when i do it i am getting
Request for member 'pData' with BOOL value TRUE is not a structure or union.
It is difficult to determine what the code is supposed to do, but here is how to create an Objective-C object that holds an integer identifier and a 4096-character array. Please note that this sort of thing is usually discouraged. Unless you have a really specific reason for using int and char[], the identifier should be NSInteger and the data should be an NSData or NSString object.
I have also used some of the "standard" naming conventions. If you are writing Cocoa code, it helps to drink a lot of the Kool-Aid.
Message.h:
#interface Message : NSObject
{
int identifier;
char data[4096];
}
#property (nonatomic, assign) int indentifier;
#property (nonatomic, readonly) char * data;
- (void)swapEndian:(BOOL)flag;
#end
Message.m:
#implementation Message
#synthesize identifier;
#synthesize data;
- (id)init
{
if ((self = [super init]) == nil) { return nil; }
identifier = 0;
data[0] = '\0';
return self;
}
- (void)swapEndian:(BOOL)flag
{
NSLog(#"%s %d", data, flag);
}
#end
main.m:
#import "Message.h"
...
Message * message = [[[Message alloc] init] autorelease];
message.identifier = 123;
[message swapEndian:YES];

In Objective-C, can I declare #property on a c-array of floats?

thing.h
#interface Thing : NSObject
{
float stuff[30];
}
#property float stuff;
#end
thing.m
#implementation Thing
#synthesize stuff;
#end
I get error: type of property 'stuff' does not match type of ivar 'stuff'
I don't want to use an NSArray because I'd have to make the floats into NSNumbers (right?) and that's a pain to do math with.
Update: I've noticed similar answers had guesses and trial answers. While I appreciate the attempts by non-Objective-C folks, I'm hoping for a definitive answer whether it's possible or not.
OK, I have compiled up the following code at it works as expected.
FloatHolder.h
#interface FloatHolder : NSObject {
int _count;
float* _values;
}
- (id) initWithCount:(int)count;
// possibly look into this for making access shorter
// http://vgable.com/blog/2009/05/15/concise-nsdictionary-and-nsarray-lookup/
- (float)getValueAtIndex:(int)index;
- (void)setValue:(float)value atIndex:(int)index;
#property(readonly) int count;
#property(readonly) float* values; // allows direct unsafe access to the values
#end
FloatHolder.m
#import "FloatHolder.h"
#implementation FloatHolder
#synthesize count = _count;
#synthesize values = _values;
- (id) initWithCount:(int)count {
self = [super init];
if (self != nil) {
_count = count;
_values = malloc(sizeof(float)*count);
}
return self;
}
- (void) dealloc
{
free(_values);
[super dealloc];
}
- (float)getValueAtIndex:(int)index {
if(index<0 || index>=_count) {
#throw [NSException exceptionWithName: #"Exception" reason: #"Index out of bounds" userInfo: nil];
}
return _values[index];
}
- (void)setValue:(float)value atIndex:(int)index {
if(index<0 || index>=_count) {
#throw [NSException exceptionWithName: #"Exception" reason: #"Index out of bounds" userInfo: nil];
}
_values[index] = value;
}
#end
then in your other application code you can do something like the following:
** FloatTestCode.h **
#import <Cocoa/Cocoa.h>
#import "FloatHolder.h"
#interface FloatTestCode : NSObject {
FloatHolder* holder;
}
- (void) doIt:(id)sender;
#end
** FloatTestCode.m **
#import "FloatTestCode.h"
#implementation FloatTestCode
- (id) init
{
self = [super init];
if (self != nil) {
holder = [[[FloatHolder alloc] initWithCount: 10] retain];
}
return self;
}
- (void) dealloc
{
[holder release];
[super dealloc];
}
- (void) doIt:(id)sender {
holder.values[1] = 10;
}
The type of the property must match the type of the instance variable it will be stored in, so you could do something like
#interface Thing : NSObject
{
float stuff[30];
}
#property float[30] stuff;
#end
and it should work. I wouldn't recommend it though.
I'm guessing you're looking for something like indexed properties from Delphi. The closest you'll get is something like the following.
#interface Thing : NSObject
{
float stuff[30];
}
- (void) setStuff:(float)value atIndex:(int)index;
- (float) getStuffAtIndex:(int)index;
#end
You can't do it the way you want to do it. You can jump through some hoops and get something similar, e.g. using Daniel's solution, but it's not quite the same thing. The reason you can't do it is that arrays are not lvalues in C. An lvalue is something that can appear on the left-hand side of an assignment. The following code is invalid C:
float stuff1[30], stuff2[30];
stuff1 = stuff2; // ERROR: arrays are not lvalues
As a consequence, you can't declare properties whose types are not lvalues.
Daniel's FloatHolder answer has a major bug (edit: he's now fixed it). It only allocates memory for one float and not for the whole array.
The line:
_values = malloc(sizeof(float));
Should be:
_values = malloc(sizeof(float) * count);
Otherwise it seems to be a good answer. Sorry couldn't work out how to reply directly. (edit: I didn't have the necessary privilege on stackoverflow then.)
Even if you could get that to compile, it wouldn't behave well. 'stuff' would return a float*, and the client would have no idea how long the array way; 'setStuff:' would just change the pointer, and you'd either be pointing to stack-allocated data that would vanish out from under you or heap-allocated data that would leak because it wouldn't know to free it.
I'm not well-versed in Objective-C 2.0, but I'm guessing that the issue might be caused by the fact that a C array is essentially just a pointer to the first element of the array, meaning that the type of float stuff[30] is actually float *, not merely a float.