'AClass' may not response to 'FunctionA' (Objective-C) - objective-c

Something about inheritance, I have two class here: female, the subclass of human, and human, it can run but showing issues.
Two issues here:
main.m:29:10: 'human' may not respond to 'setSexy:'
main.m:30:10: 'human' may not respond to 'isSexy'
main.m
#import <Foundation/Foundation.h>
#import "female.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
human *sexyGirl = [[female alloc] init];
[sexyGirl setName:#"SexyGirl"];
[sexyGirl setGender:0];
[sexyGirl setSexy:1];
[sexyGirl isSexy];
}
return 0;
}
female.h
#import "human.h"
#interface female : human {
BOOL sexy;
}
#property BOOL sexy;
-(void)isSexy;
#end
human.h
#import <Foundation/Foundation.h>
#interface human : NSObject {
NSInteger *hp;
NSString *name;
BOOL gender;
}
#property (assign, nonatomic) NSInteger *hp;
#property (assign, nonatomic) NSString *name;
#property (assign, nonatomic) BOOL gender;
-(void) walk;
#end

There is no method name isSexy and setSexy in human class
You should change this human *sexyGirl = [[female alloc] init];
to this female *sexyGirl = [[female alloc] init];

when you do : human *sexyGirl = [[female alloc] init];
you upcast the female to human. all the extra information (extra methods) a female has are still there but no longer visible
you can only work with what a human has from then on OR you downcast the variable again.
[(female*)sexyGirl setSexy:1];
[(female*)sexyGirl isSexy]
alternativly never downcast it and declare it as female * all the way

Related

Optimization - pull into local variable or leave to the compiler?

I was writing some code where I have a bunch of nested NSSets through classes, something like the following:
#interface C : NSObject
#property (nonatomic) NSString *name;
#end
#interface B : NSObject
#property (nonatomic) NSMutableSet<C *> *cset;
#property (nonatomic) NSString *name;
#end
#interface A : NSObject
#property (nonatomic) NSMutableSet<B *> *bset;
#property (nonatomic) NSString *name;
#end
And at some point, I have a function that iterates over each and every element and uses its (and the parents') names:
for (B *b in a.bset)
{
for (C *c in b.cset)
{
addToDict(a.name, b.name, c.name);
}
}
And I was wondering, is it faster to pull out these calls into a local variable? So instead of the above, we end up with something like:
NSString *aname = a.name;
for (B *b in a.bset)
{
NSString *bname = b.name;
for (C *c in b.cset)
{
NSString *cname = c.name;
addToDict(aname, bname, cname);
}
}
Would the second be faster? Normally, I would think compiler optimization should recognize the temporal usage of each variable, but I wasn't sure since each one is inside a class.

Access annotated property in Objective-C

I’ve searched around for this but found no information at all. Say I create a property like so:
#property (nonatomic, strong, readwrite) NSString *someString __attribute((annotate(“Try to access this text?)));
How could I access the text in the annotation part of the property? I’m guessing I’d have to utilize Objective-c runtime but I found no information there either.
First off, sales pitch - swift would make this easily transparent with optionals. Since you are using objective-c here's how I would do it:
#interface SomeModel {
static NSString * const _requiredProperties[] = {
[0] = #"first",
[1] = #"second"
};
}
#property(nonatomic, strong) NSString *first;
#property(nonatomic, strong) NSString *second;
#end
-(BOOL) doLoad:(...) {
//map properties here
Bool success = YES;
foreach(NSString property in _requiredProperties {
success &= ([self valueForKey: property] != nil);
}
return success;
}
The objective-C language doesn't contain the types of constructs you need. Keep it simple, handle missing properties elegantly.
Also if it's JSON, there's plenty of frameworks available to help. Unsure of your mapping here.
Alternatively you can query the protocol, and use the fact it is in a protocol to determine if required.
See this hello world like example that prints out the protocols in the required protocol - sadly the third param which is "YES" for required seems to include optionals for me on OSX. So I made a separate protocol for optionals. This might help you.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#protocol TestProtocolRequired
#required
#property(nonatomic, strong) NSString *firstName;
#property(nonatomic, strong) NSString *lastName;
#end
#protocol TestProtocolExtended
#property(nonatomic, strong) NSString *address;
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
unsigned int outCount, i;
objc_property_t *properties = protocol_copyPropertyList2(#protocol(TestProtocolRequired), &outCount, YES, YES);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
}
return 0;
}
It prints out
firstName T#"NSString",&,N
lastName T#"NSString",&,N

any mistakes using #property and #synthesize

I'm a newbie of Objective-C language and I'm trying to understand the basic concepts. I came from Java language so I have already know the principle of OOP programming. Here it is the code I wrote. It's very simple but it doesn't work properly. I have some issues using #property and #synthesize
#import <Foundation/Foundation.h>
#interface Car: NSObject
#property(nonatomic,retain) NSString *brand;
#property int year;
#end //Car Interface
#import "Car.h"
#implementation Car
#synthesize brand;
#synthesize year;
#end //Car Implementation
#import "Car.h"
int main (int argc, const char * argv[])
{
int y;
//Creo un nuovo oggetto
Car *myCar = [[Car alloc] init];
//Setto i parametri
[myCar setbrand: #"BMW Z4"];
NSLog (#"Inserisci data modello: ");
scanf (" %i", &y); //E' buona norma lasciare uno spazio
[myCar setyear: y];
//Stampo a video i dati
NSLog(#"Marca: %# Anno: %i", [myCar setbrand], [myCar setyear]);
}
I don't know where it's the error. I'm pretty sure there is some mistakes in main function. is it correct call that methods in that way?
The setters must be capitalized properly.
[myCar setBrand:#"BMW Z4"];
[myCar setYear:2010];
The getters default to the property name.
NSString *carBrand = [myCar brand];
int carYear = [myCar year];

NSArray as Private data in Class?

I recently started learning Objective-C. I decided to make a class called "Student" with the properties age, name, and importantly, classes. I have put the classes in an NSArray full of NSStrings. My issue is, if I define it as an #property, it automatically creates a setter and getter method for it. I dont want that in my class. How do I define an NSArray as private data in the class, without allowing for the setter and getter?
Here's the header code:
#import <Foundation/Foundation.h>
#interface Student : NSObject
#property NSString * Name;
#property unsigned short age;
#property BOOL isFullTime;
#property NSMutableArray * Classes;
#end
[NSGreeter ThanksGuys];
You have a few popular options. Of course, you can substitute types as you wish:
A:
Place it in the header, and specify #private access.
// Student.h
#interface Student : NSObject
{
#private // << note: protected is the default when declared in this scope.
NSArray * ivar;
}
#end
B:
Place it in the #implementation block. you could specify access, but that is not usually an issue because it is not visible to any other translation.
// Student.m
#implementation Student
{
#private // << note: private is the default when declared in this scope.
NSArray * ivar;
}
#end
C:
Declare it in the class continuation:
// Student.m
#interface Student ()
{
NSArray * ivar;
}
#end
D:
Declare as a property in the class continuation:
// Student.m
#interface Student ()
#property (nonatomic, copy) NSArray * ivar;
#end
#interface Student : NSObject {
#private
NSMutableArray * Classes;
}
#property NSString * Name;
#property unsigned short age;
#property BOOL isFullTime;
#end
Use the keyword #private
#interface Student : NSObject
{
#private
NSMutableArray * Classes;
}
#property NSString * Name;
#property unsigned short age;
#property BOOL isFullTime;
#end

iOS – NSMutableArray and Block Copy

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.