JoBu1324
JoBu1324

Reputation: 7769

How can you allocate a class in objective-c from NSString object?

I've got a PHP background, but I'm beginning to learn Objective-C, so that I can develop apps for the iPhone. So far things are going pretty well, but I've got a question that I haven't been able to find and answer to yet after googling and mining a number of different forums.

My app has to create a number of views, each with it's own uinque title bar. In order to do this, my code looks something like this for each view:

    xViewController = [ [ XViewController alloc ] init ];
    xNavController = [ [ UINavigationController alloc ]
        initWithRootViewController: xViewController
    ];
    xNavController.tabBarItem = [ [ UITabBarItem alloc ]
        initWithTitle: @"My Info"
        image: [ UIImage imageNamed: @"my_info.png" ]
        tag: 3
    ];  

This works, but what I'd like to do is to create a method that will return a nav controller when sent a string as a message, so I don't have to do all this for each view. The issue I am having is that the first line needs to allocate an object based on a class name passed to it as a string (i.e. XViewController needs to be taken from a string passed to the method), but I don't know how to treat a string as a class name. I know it's possible, because the UIApplicationMain() can use a string to call the app delegate class. How can I do it?

I'm sorry if any of this doesn't make sense, I'm still in the early stages of learning a new language!

Upvotes: 2

Views: 4063

Answers (4)

Sold Out Activist
Sold Out Activist

Reputation:

If you have multiple TableViewCells loaded from NIBs, the code to load the individual NIBs gets ugly if you don't do something with dynamic loading.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // header
    if (indexPath.row == 0) {
        cellHeader *cell = (cellHeader *)[self loadCell:identHeader];
        return cell;

    // load more
    } else if (indexPath.row == lastRow) {
        loadMore *cell = (loadMore *)[self loadCell:identLoadMore];
        return cell;
    }

    // default
    cellDefault *cell = (cellDefault *)[self loadCell:identDefault];
    return cell;
}

- (id)loadCell:(NSString *)className {
    id cell = [tweetsView dequeueReusableCellWithIdentifier:className];

    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:className owner:nil options:nil];

        for (id currentObject in topLevelObjects) {
            if ([currentObject isKindOfClass:[UITableViewCell class]]) {
                cell = currentObject;
                break;
            }
        }
    }

    return cell;
}

Upvotes: 1

diederikh
diederikh

Reputation: 25271

If I understand your problem correctly you don't need dynamic classes to make this work. Why not create, for each view controller class, its unique title and image method that just returns the unique title and image for that view controller. Then create a super class for your view controller classes with dummy title and image methods.

Your code above will then look something like this:

- (UINavigationController *)getNavController:(XGenericViewController *)viewController
{
        UINavigationController  *xNavController = [ [ UINavigationController alloc ]
            initWithRootViewController: viewController
        ];
        xNavController.tabBarItem = [ [ UITabBarItem alloc ]
            initWithTitle: [viewController title]
            image: [viewController image]
            tag: 3
        ];

    return [xNavController autorelease];
}

Upvotes: -1

Jason Coco
Jason Coco

Reputation: 78353

As well as using the runtime, you can do it just using Cocoa-touch methods:

NSString* theClassName = /* assume this exists */
Class theClass = NSClassFromString(theClassName);
NSObject* myObject = [[theClass performSelector:@selector(alloc)] init];
// do something with the new object instance

Upvotes: 19

J-16 SDiZ
J-16 SDiZ

Reputation: 26910

Use Objective-C 2.0 Runtime Reference

Upvotes: 0

Related Questions