Iphone: How to get all attributes of a class? - iphone

I have this class:
#interface Mission : BaseModel
{
NSString *Description;
NSDate *EndDate;
NSMutableArray *MissionSectionList;
NSString *Name;
NSDate *StartDate;
}
#property (nonatomic, retain) NSString *Description;
#property (nonatomic, retain) NSDate *EndDate;
#property (nonatomic, retain) NSMutableArray *MissionSectionList;
#property (nonatomic, retain) NSString *Name;
#property (nonatomic, retain) NSDate *StartDate;
#end
Is it possible to find out all the atrributes of this class?
I tried it with
Ivar class_getClassVariable(Class cls, const char* name)
But I don't know what the name should be:
name: The name of the class variable definition to obtain.
And actually I want to get all of them without knowing the name.
Is this possible?

You can use class_copyIvarList function to get the list of all instance variables of the class. Then you can iterate through it to get attributes of each ivar. (Note that you're responsible for freeing memory used for ivars array). Sample code may look like:
unsigned int count;
Ivar *varList = class_copyIvarList([Mission class],&count);
for (int i = 0; i < count; ++i){
Ivar var = varList[i];
// Do when you need with ivar
}
free(varList);

Related

Singleton changes is not preserved to the next view IOS

I have a singleton class which I intend to share throughout my whole application.
It looks like this:
.m
#implementation PersonalGlobal
#synthesize firstName;
#synthesize lastName;
#synthesize SSN;
#synthesize customerNo;
#synthesize email;
#synthesize address;
#synthesize city;
#synthesize postalCode;
#synthesize telNo;
#synthesize mobileNo;
#pragma mark Singleton Methods
+ (id)sharedPersonal {
static PersonalGlobal *sharedPersonalGlobal = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedPersonalGlobal = [[self alloc] init];
});
return sharedPersonalGlobal;
}
- (void)dealloc {
[super dealloc];
// Should never be called
}
#end
.h
#import <foundation/Foundation.h>
#interface PersonalGlobal : NSObject {
NSString *firstName;
NSString *lastName;
NSString *SSN;
NSString *customerNo;
NSString *email;
NSString *address;
NSString *city;
NSString *postalCode;
NSString *telNo;
NSString *mobileNo;
}
#property (nonatomic, retain) NSString *firstName;
#property (nonatomic, retain) NSString *lastName;
#property (nonatomic, retain) NSString *SSN;
#property (nonatomic, retain) NSString *customerNo;
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *address;
#property (nonatomic, retain) NSString *city;
#property (nonatomic, retain) NSString *postalCode;
#property (nonatomic, retain) NSString *telNo;
#property (nonatomic, retain) NSString *mobileNo;
+ (id)sharedPersonal;
#end
In the code I save strings to it like so:
PersonalGlobal *sharedPersonal = [PersonalGlobal sharedPersonal];
sharedPersonal.firstName = #"Some string";
But when I change view and try to access the string like this:
PersonalGlobal *sharedPersonal = [PersonalGlobal sharedPersonal];
//Setting some textfield
sometextfield.text = sharedPersonal.firstName;
I get nothing. I have done a #import "PersonalGlobal.h" in all the files.
Can i commit the changes in any way to the singleton class?
Can anyone see what I am doing wrong here?
Thanks!
Your implementation is looking fine. This should work if your singleton returning the only one instance . So the point of doubt in your sharedPersonal method . Just try to add breakpoints in this method and see whether it is creating a new instance every time .for the reference I got this SO question.
If not then you can also try this :
+(SingleTon *)getSharedInstance
{
static PersonalGlobal *sharedPersonalGlobal = nil;
if (sharedPersonalGlobal==nil)
{
sharedPersonalGlobal=[[PersonalGlobal alloc]init];
}
return sharedPersonalGlobal;
}
This is working code for me.
Your singleton implementation looks ok. I wouldn't be surprised if in this case the code that you wrote to set the firstName just never gets executed. If I were you I would step through the codes.

EXC_BAD_ACCESS when accessing UIDatePicker

I want to read the value from my DatePicker and store it in my singleton, but I get an exception when trying to do this.
Here is the singleton interface:
#interface Helper : NSObject {
NSMutableArray *array;
//Information For Filter page
NSMutableArray *towns;
NSMutableArray *types;
//Shared resources to apply filters
NSDate *toDate;
NSDate *fromDate;
NSString *selectedType;
NSString *selectedTown;
//Shared resource of which button was clicked
int clicked;
int clickedCell;
int clickedContext;
}
#property (nonatomic, retain) NSMutableArray *array;
#property (nonatomic, retain) NSMutableArray *towns;
#property (nonatomic, retain) NSMutableArray *types;
#property (nonatomic) int clicked;
#property (nonatomic) int clickedCell;
#property (nonatomic) int clickedContext;
#property (nonatomic, retain) NSDate *toDate;
#property (nonatomic, retain) NSDate *fromDate;
#property (nonatomic, retain) NSString *selectedType;
#property (nonatomic, retain) NSString *selectedTown;
+(id)sharedManager;
#end
This is the function where the exception happens
-(void) viewWillDisappear:(BOOL)animated
{
Helper *myHelper = [Helper sharedManager];
if(myHelper.clickedContext == 0)
{
if(myHelper.clickedCell == 0)
{
//causes exception
myHelper.fromDate = [self.fromDatePicker date];
}
else
{
//causes exception
myHelper.toDate = [self.toDatePicker date];
}
}
else
{
if(myHelper.clickedCell == 0)
{
myHelper.selectedTown = [myHelper.towns objectAtIndex:[self.townPicker selectedRowInComponent:0]];
}
else
{
myHelper.selectedType = [myHelper.types objectAtIndex:[self.typePicker selectedRowInComponent:0]];
}
}
[super viewWillDisappear:animated];
}
declaration of pickers
#property (nonatomic, retain) IBOutlet UIDatePicker *toDatePicker;
#property (nonatomic, retain) IBOutlet UIDatePicker *fromDatePicker;
#property (nonatomic, retain) IBOutlet UIPickerView *typePicker;
#property (nonatomic, retain) IBOutlet UIPickerView *townPicker;
#synthesize part
#synthesize typePicker, toDatePicker, fromDatePicker, townPicker, townsView, toDateView, typesView, fromDateView;
Any idea's why?
Thanks
If your outlet is not assigned in interface builder this can happen.
If you think it is, try running the app with NSZombieEnabled = YES and see if you get any error messages.
I found the problem. In my Helper Class I should have assigned not retained. So it should have been
#property (nonatomic, assign) NSDate *toDate;
#property (nonatomic, assign) NSDate *fromDate;

Obj-c: Custom Object handling

I am creating my own custom object, and I am wondering if I need to retain my properties or use something else such as copy (which does what?)?
#interface Asset : NSObject {
NSString *name;
NSNumber *assetId;
NSNumber *linkId;
NSNumber *parentId;
}
#property (nonatomic, retain) NSString *name; // should I use retain here or something else?
#property (nonatomic, retain) NSNumber *assetId;
#property (nonatomic, retain) NSNumber *linkId;
#property (nonatomic, retain) NSNumber *parentId;
#end
Also, in my .m, do I also need synthesize as well as release?
The chapter on Declared Properties in The Objective-C Programming Language explains what copy does and about synthesizing accessors.
My personal preference:
#interface Asset : NSObject {
// no need to declare them here the #synthesize in the .m will sort all that out
}
// use copy for NSString as it is free for NSString instances and protects against NSMutableString instances being passed in...thanks to #bbum for this
#property (nonatomic, copy) NSString *name;
// no need for copy as NSNumber is immutable
#property (nonatomic,retain) NSNumber *assetId;
#property (nonatomic,retain) NSNumber linkId;
#property (nonatomic,retain) NSNumber parentId;
#end
For typical cases your .m will have lines like this:
#synthesize name;
...
That tells the compiler to automatically emit the getter/setter methods. You can also write/override these yourself.
So, when someone does a fooAsset.name = x, your object will retain its own reference to 'x'.
The other thing you need is a dealloc method to release the references to your members:
- (void)dealloc {
[name release];
....
[super dealloc];
}
Note that it'll still be appropriate if 'name' is never assigned; nil will silently eat the 'release' message.

Simple Question about Core Data

I using the project named coredatabooks from apple developer examples.
#import
#interface Book : NSManagedObject
{
}
#property (nonatomic, retain) NSNumber *active;
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSString *author;
#property (nonatomic, retain) NSDate *copyright;
#end
I need to use a bool object, but I don't know how to implement it in my class.. I'm using right now NSNumber, using an integer (0, 1) but is not a Bool... maybe it will be more correct to use this ...
#property (nonatomic, retain) bool active;
but is not working.
You can still use an NSNumber, but pack it from a bool:
[NSNumber numberWithBool: myBool];
and unpack it to a bool:
[myNSNumber boolValue];

Error: request for member theSizes something not a structure or union

I'm getting this same error, but I've checked to make sure the properties were set correctly in the .h file.
Here's the code:
NSUInteger theSizesCount = [theWho.theSizes count];
The error is "error: request for member theSizes in something not a strucutre or union. This .m file is importing 6 .h files, and 4 of them have the same properties in theWho, but it's related to various Super Classes. This .m file is implementing only one of them, and theWho and theSize are sythesized.
Also, in this code, and theSizes variable is green, but theWho variable is not. Plus, the error is happening in multiple places for NSUIntegers, NSMutableArray etc.
Where am I going wrong? Some of the header file code is below.
// TheSize.h
#class TheWho;
#interface TheSize : NSManagedObject
{
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *amount;
#property (nonatomic, retain) TheWho *theWho;
#property (nonatomic, retain) NSNumber *displayOrder;
#end
and..
//
// TheWho.h
//
#interface ImageToDataTransformer : NSValueTransformer {
}
#end
#interface TheWho : NSManagedObject {
}
#property (nonatomic, retain) NSString *instructions;
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSSet *theSize;
#property (nonatomic, retain) UIImage *thumbnailImage;
#property (nonatomic, retain) NSManagedObject *image;
#property (nonatomic, retain) NSManagedObject *type;
#end
#interface TheWho (CoreDataGeneratedAccessors)
- (void)addTheSizesObject:(NSManagedObject *)value;
- (void)removeTheSizesObject:(NSManagedObject *)value;
- (void)addTheSizes:(NSSet *)value;
- (void)removeTheSizes:(NSSet *)value;
#end
I checked my declarations again, and I had to add an "s" to the NSSet *theSize entry. Those errors are gone. Thanks all for the help.
You still need to define the member variables. The #property directive declares the accessor methods, not the underlying members.
#interface TheWho : NSManagedObject {
NSString *instructions;
NSString *name;
NSSet *theSize;
UIImage *thumbnailImage;
NSManagedObject *image;
NSManagedObject *type;
}
You're trying to access theWho.theSizes but according to your header file, you should be trying theWho.theSize (without the trailing s).
Unless, there's a typo in how you've typed it here, and it wasn't copied directly.