is alloc not available for my object? - ios

I created a few custom objects, where one holds a container of the other.
The interface for ClassObject has a publicly declared init function like this:
#interface ClassObject : NSObject
#property NSDate *earliestDate;
#property NSDate *latestDate;
- (id) initWithHKQuantitySample: (HKQuantitySample *)sample;
#end
So I'd like to do the following:
ClassObject * newObject = [[ClassObject alloc] initWithClass2Object:sample];
However, I am being stopped because Xcode is not recognizing alloc as a valid selector and is only suggested alloca(size_t), which is most definitely not what I want.
What am I doing wrong?
This seems like such a basic thing, I can't figure out what I am missing or have forgotten.
Thanks for any suggestions!

If you haven't imported the header file for your custom class, it won't be recognized by Xcode. Wherever you want to use ClassObject, you should make sure you have this:
#import "ClassObject.h"
Other than that, your class looks fine to me.

Related

Allow change in property only from one specific class

Suppose I have a class Participant which looks like this
Participant.h
#interface Participant : NSObject
#property(nonatomic, readonly) NSString *name;
#property(nonatomic, readonly) NSString *id;
#end
Here properties are readonly because I don't want anyone using this interface to change it
Besides ParticipantManager.h
What changes should I do in Participant class and how would I create ParticipantManager such that only ParticipantManager can change properties of Participant
More context
I get an event from react-native when value changes. to keep things in sync, I want my interface ParticipantManager to only change the values.
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#interface ParticipantManager : RCTEventEmitter <RCTBridgeModule>
#end
^^ Above class should only be able to change properties of Participant class
For a user to change a value, he would call changeName method, which will send an event back to react-native where react-native would change value and send back to native code
what I have tried.
So, I thought about using class extensions concept but I am getting an error.
Here is what I did
I create Participant+Private.h which implements setName method
#import " Participant.h"
interface Participant()
- (void)setName:(NSString)name
- (void)setId:(NSString)name
#end
PS: I implemented setName and setId method in Participant.h
- (void)setName:(NSString)name {
_name = name;
}
but then when I am using it in my ParticipantManager.h, it is throwing error
No visible #interface for Participantdeclares the selector
setName
I am using it like this
#import "Participant+Private.h"
NSString* value = #"varun";
[[Participant sharedInstance] setName:value];
Can someone help me in fixing error?
Slightly detailed question here:
No visible #interface for Participant declares the selector setName
Objective-C doesn't provide that sort of reasoned privacy, e.g. "I am private to everyone except one other specific class which I hereby name". (Actually, I don't know any language that behaves that way, but that's not to say that there are no such languages of course.)
If this is a framework, you can use #package privacy to confine the privacy of something to other classes in the same framework.
Otherwise, Objective-C generally solves the visibility problem by importing headers, so if you put public accessors for Participant into a header and the only class that imports that header is ParticipantManager, then only ParticipantManager sees them.

How to create a new object and assign properties in Objective-C?

I'm trying to bridge an Objective C SDK with React Native and I'm having some trouble. I have a Subclass of NSObject and I'm trying to set some property values but I can't get it to work.
I have tried to change the property in the header, and in the imp file with out any difference.
PrinterSDK.h (which has libPrinterSDK.a)
#interface Printer : NSObject
#property (nonatomic, readonly) NSString* name;
#property (nonatomic, readonly) NSString* UUIDString;
#end
RNPosPrint.m
#interface Printer ()
#property (readwrite) NSString* name;
#property (readwrite) NSString* UUIDString;
#end
RCT_EXPORT_METHOD(printTestPaper:(NSString*)name:(NSString*)uuid)
{
Printer* printer = [[Printer alloc] init];
printer.name = name;
}
But I keep facing issue with the setter for some reason I can't figure out.
ExceptionsManager.js:94 Exception '-[Printer setPrinterName:]: unrecognized selector sent to instance 0x13fd25b90' was thrown while invoking printTestPaper on target RNPosPrint with params (
"Test Printer",
"XXX-XXX-XXX"
)
You do not report the names of your .h and .m files or what else is in the .m – e.g. #implementation of Printer? The class printTestPaper belongs to? Without details like this it is difficult for anyone to help you, you need to help people help you.
That said some points that may help you:
The #interface Printer () where you open up the properties to be writeable should be in the your Printer.m file – in general do not try to open up access to a type's properties from outside the type's implementation, it is both bad design and may not work as you hope (as you just found out).
The code to support a #property is generated by the compiler when it compiles the #implementation, #interface's themselves produce no executable code – they describe the accessible parts of the #implementation.
setter=<name> provides a different name for the auto-created property setter function. While a method <name> will be created to set the property using dot syntax the properties name is still used, e.g. in your case printer.name = ... is still used even with the setter=setPrinterName:. You can call the auto-created method using standard method syntax, that failed in your case for the reasons above.
Using setter=<name> or getter=<name> are really advanced features and you probably will never need to use them – when you do need to use them you will know! Just avoid them till then.
If you wish to provide a method which creates the object and sets properties then do this in the type's implementation. The usual way of doing this is to provide an init method that does this, e.g. in this case it might be - initWithName:(NSString *)printerName { ... }, or an equivalent class method which does the allocation and sets the parameters, e.g. in this case it might be + newWithName:(NSString *)printerName { ... }.
HTH
Since it's an interface from statically linked library it is simply not possible to extend or manipulate. Not without tempering with the compiler.

objc incompatible pointer type with protocol inheritance

I am running with Xcode version 5.1, iOS SDK version 7.1.
Here are some sample declarations all in the same file:
#protocol A <NSObject>
#end
#protocol B <A>
#end
#interface SomeObject : NSObject <B>
#end
#interface SomeContainer : NSObject
- (id<A>)pop;
#end
Xcode generates a warning in the following code:
SomeContainer *container = [[SomeContainer alloc] init];
SomeObject *obj = [container pop]; // Warning: Initializing 'SomeObject *__strong' with and expression of incompatible type 'id<A>'
I know that typecasting will get rid of the warning, however, I don't understand why I need it. SomeObject must implement whatever is declared in protocol A. Is there something that I am missing? Any explanation would be greatly appreciated.
Probably this is because SomeObject is something more than just id<A>. It's like initialising an object of derived class with pointer to the base class. You can initialize an instance of id<A> with SomeObject but when you do it vice versa you're receiving a warning, which says :"Hey, buddy you've just assigned base to derived, i.e. something that is present in derived (SomeObject *) may be missed in base id<A>"
for example SomeObject may contain method foo which is not present in protocol A, but now after that assignment of yours if you send foo message to obj it may crash, because id<A> is not necessarily has this method. It can, if it's also an instance of SomeObject, but it can be anything, which NECESSARILY responds only to the methods declared in A.
I hope all this makes sense

Im working on "Matchismo" the app for the stanford itunes university courses, and on the first assignment I get an issue on my PlayingCrad.m file.

#import "PlayingCard.h"
#implementation PlayingCard
-(NSString *)contents
{
NSArray *rankStrings = [PlayingCard rankStrings];
return [rankStrings[self.rank] stringByAppendingString:self.suit];
/Users/Pichard93/Desktop/Matchismo2/Matchismo2/PlayingCard.m:18:33: Property 'rank' not found on object of type 'PlayingCard'
//This is the issue i get ^^
It looks like rank should be declared as a property and is not. Declare it the interface file or as a class extension in the implementation file.
Basically the error messages do mostly make sense, try to figure out what them mean pertaining to your code. In this case the error message rather explicitly stated that rank is not found for the class PlayingCard which means not declared.
Add this line to your PlayingCard.h
#property (nonatomic)NSUInteger rank;

Assign Enum to Variable in Objective-C

How can I assign an enum to a variable and access its value later? I thought this would be pretty simple, but every time I try to assign the enum value to a variable (no type mismatches or warnings in Xcode appear) my app crashes with an EXC_BAD_ACCESS error.
Here's how I setup my enum in my header file (BarTypes.h):
typedef enum {
BarStyleGlossy,
BarStyleMatte,
BarStyleFlat
} BarDisplayStyle;
No issues there (reading and using the values at least). However, when I create a variable that can store one of the enum values (BarStyleGlossy, BarStyleMatte, or BarStyleFlat) then try to set that variable, the app crashes. Here's how I setup and use the variable:
//Header
#property (nonatomic, assign, readwrite) BarDisplayStyle barViewDisplayStyle; //I've also tried just using (nonatomic) and I've also tried (nonatomic, assign)
//Implementation
#synthesize barViewDisplayStyle;
- (void)setupBarStyle:(BarDisplayStyle)displayStyle {
//This is where it crashes:
self.barViewDisplayStyle = displayStyle;
}
Why is it crashing here? How do I store the value of an enum in a variable? I think the issue has to do with a lack of understanding about enums on my end, however if I follow conventional variable setup and allocation, etc. this should work. Any ideas on what I'm doing wrong?
Please note that I'm new to enums, so my vocabulary here may be a bit mixed up (forgive me - and feel free to make an edit if you know what I'm trying to say).
I found a few references about enums across the web:
What is a typedef enum in Objective-C?
Using enum types as properties in Objective C
How to create global enum
How do I define and use an ENUM in Objective-C?
I also tried searching Apple's Developer site but only came up with results about types for Apple APIs (ex. Foundation, UIKit, etc.)
EDIT: Here's how I call the setupBarStyle method:
BarView *bar = [[BarView alloc] init];
[bar setupBarStyle:displayStyle];
Just in case anyone out there is still trying to figure out how to assign an enum value to an enum typed variable or property...
Here is an example using a property.
In the header file...
#interface elmTaskMeasurement : NSObject
typedef NS_ENUM(NSInteger, MeasurementType) {
D,
N,
T,
Y,
M
};
#property(nonatomic) MeasurementType MeasureType;
#end
In the file where the object is created...
elmTaskMeasurement *taskMeasurement = [[elmTaskMeasurement alloc] init];
taskMeasurement.MeasureType = (MeasurementType)N;
The method you implement is called setupBarStyle:, but you call setupBarShape: on the object.
I had this error myself but the error was caused by a different bug I off course create myself.
The setter of my property "myApplicationState" was as follows:
-(void)setApplicationStyle:(myApplicationStyle)applicationStyle{
self.applicationStyle = applicationStyle;
//some more code
}
Off course this would result in an endless loop because in the setter, the setting is called again, and again, and again.
It had to be:
-(void)setApplicationStyle:(myApplicationStyle)applicationStyle{
_applicationStyle = applicationStyle;
//some more code
}

Resources