views:

99

answers:

4

Hey all. I know this sounds simple, but I can't find a way to do it. I have a method in Obj-C that takes in a NSString and then should create a new class with the String as its title.

-(DataModel *)createDataModel:(NSString *)dataModel_name {
        DataModel *[initWithString:dataModel_name] = [[DataModel alloc] init];
        }

I know I have some problems in this. For starters, I don't know how to define a return on an object whose name could change. Second, I know this doesn't compile considering the initWithString method is wrong. I just don't know what to do or what method to use so that I can create this DataModel object with the specified name...

A: 

NSClassFromString() will do what you want. Also, initially declaring variables as type id allows you to set their explicit type later on. So:

id dataModel = [[NSClassFromString(dataModel_name) alloc] init];
jshier
I think I mis-spoke. I want to make the name of the object, which is dataModel, dynamically titled by the String being passed to the method. Essentially, it should be: DataModel *(STRING PASSED TO METHOD) = [[DataModel alloc] init];
FnGreg7
@FnGreg7: But why would you need to do so? The caller of your method doesn't care how you name the local variable that holds the pointer the object.
Georg Fritzsche
A: 

If your title is setup correctly, as a property:

-(DataModel *)createDataModel:(NSString *)dataModel_name {
    DataModel *model = [[DataModel alloc] init];
    model.title = dataModel_name;
    return model;
}

That would require in your datamodel.h:

@interface DataModel {
  NSString *title;
}
@property (nonatomic, retain) NSString *title;
@end

And in your .m:

@implementation DataModel
@synthesize title;
@end

But your question isn't clear if your real purpose is trying to instantiate different classes based on the dataModel_name or if you just have a single generic class with a title that should be set to dataModel_name.

Depending on what you want to do, there are different answers. If you really want different classes based on the name, then you should do things differently. You can use the Cocoa specific type: id, to return any object from a method. Then the method, NSClassFromString() to create the object:

- (id)createDataModel:(NSString *)dataModel_name {
   id model = [[NSClassFromString(dataModel_name) alloc] init];
   [model setTitle:dataModel_name];
   return model;
}

Or you can define a Protocol (Interface in java parlance) that declares the features of your data model. Your method would return that instead.

Mike
Will the setTitle name change the name of the object? You're still returning the object named "model". I want the NSString *dataModelName to BECOME the name of the DataModel object. Such that when I input the string into the method, I am returned a DataModel object named what the string I put in was.
FnGreg7
What do you mean by "the name of the object"? There isn't really any inherent "name" to an Objective-C object. Objects have a "Class" (which you probably don't want to create dynamically, as drawnonward says), and they can have whatever properties like "title" you choose (as in this example).
David Gelhar
Objects don't have names (in the sense that you're using "name"). Classes have names. Variables have names. Variables can hold references to objects. If you want to give your objects names, you can stick them in a NSDictionary and access them by name.
Steven D. Majewski
A: 

To locate or create a new class:

Class arbitraryClass = NSClassFromString(dataModel_name);
if ( nil == arbitraryClass ) arbitraryClass = objc_allocateClassPair( [DataModel class] , [dataModel_name UTF8String] , 0 );

To create a new instance of an object with your newly created class:

DataModel *modelWithArbitratyClassName = [[arbitraryClass alloc] init];

Creating new classes at runtime is not usually a good idea.

drawnonward
A: 

So, it seems you want to dynamically add an Instance variable to an object at runtime. You don't get this for free. CALayer and CAAnimation can do something similar to this, you can read about it here

You could add similar functionality to your own objects using Key-value-coding, and more specifically the method valueForUndefinedKey. There will be some KVC specific caveats so you should really make sure you are familiar with and understand KVC. Take a look at this, it might be just want you want.

A dictionary is used to store the value and key, and to retrieve the value when you try to access it.

mustISignUp