Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 05-29-2011, 12:11 AM   #1 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Arrow *VARIABLE*FromString:

Code:
for (int mainViewNumber = 1; ; mainViewNumber++) {
        NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
        UIView *mainView = [[UIView alloc] init];
        mainView = mainViewName;
        if (mainView == nil) {
            break;
        }
        [cvMainViewScrollView addSubview:mainView];
        NSString *log = [[NSString alloc] initWithFormat:@"Added %@ to mainview!", mainViewName];
        NSLog(log);
    }
I made this code to add 5 UIViews (map1MainView, map2MainView, ...) to UIScrollView cvMainViewScrollView.

I know you can't make UIView MainView an NSString (in green) but I'm wondering how I can get it to do what I'm explaining.

How do I turn that string into a UIView so I can assign it to mainView and add it?
UnretroGamer is offline   Reply With Quote
Old 05-29-2011, 02:43 AM   #2 (permalink)
Registered Member
 
Join Date: Feb 2011
Location: Northern California
Posts: 9
zpasternack is on a distinguished road
Default

I think you're looking for NSClassFromString.


Code:
NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
UIView *mainView = [[NSClassFromString(mainViewName) alloc] init];
zpasternack is offline   Reply With Quote
Old 05-29-2011, 06:10 AM   #3 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Wink

Quote:
Originally Posted by zpasternack View Post
I think you're looking for NSClassFromString.


Code:
NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
UIView *mainView = [[NSClassFromString(mainViewName) alloc] init];
Thanks for the reply, here's my code so far:

Code:
for (int mainViewNumber = 1; mainViewNumber < 5; mainViewNumber++) {
        NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
        UIView *mainView = [[NSClassFromString(mainViewName) alloc] init];
        if (mainView == nil) {
            NSLog(mainViewName);
        }
        [cvMainViewScrollView insertSubview:mainView atIndex:mainViewNumber];
        mainView.center = CGPointMake(commandView.center.x + (mainView.frame.size.width * (mainViewNumber - 1)), commandView.center.y);
        NSString *log = [[NSString alloc] initWithFormat:@"Added %@ to mainview!", mainViewName];
        NSLog(log);
    }
That brought up no errors, but it also didn't do anything. It isn't putting anything in UIView mainView. Everything is returned nil, and nothing is displayed in the scroll view in the app.

map1MainView, map2MainView, ... are variables I declared in the header file and synthesized in the implementation file that are connected to isolated views in Interface Builder. I'm trying to turn the string into a variable.
UnretroGamer is offline   Reply With Quote
Old 05-29-2011, 07:04 AM   #4 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by UnretroGamer View Post
Thanks for the reply, here's my code so far:

Code:
for (int mainViewNumber = 1; mainViewNumber < 5; mainViewNumber++) {
        NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
        UIView *mainView = [[NSClassFromString(mainViewName) alloc] init];
        if (mainView == nil) {
            NSLog(mainViewName);
        }
        [cvMainViewScrollView insertSubview:mainView atIndex:mainViewNumber];
        mainView.center = CGPointMake(commandView.center.x + (mainView.frame.size.width * (mainViewNumber - 1)), commandView.center.y);
        NSString *log = [[NSString alloc] initWithFormat:@"Added %@ to mainview!", mainViewName];
        NSLog(log);
    }
That brought up no errors, but it also didn't do anything. It isn't putting anything in UIView mainView. Everything is returned nil, and nothing is displayed in the scroll view in the app.

map1MainView, map2MainView, ... are variables I declared in the header file and synthesized in the implementation file that are connected to isolated views in Interface Builder. I'm trying to turn the string into a variable.
You're trying to look up an object by using a string which is the name of that object?

There's not really a way to do that.

The closest you can come is to put all the objects you want to look up by name into a dictionary:

Code:
UIView* firstView = [UIView initWithFrame: firstFrame];
UIView* secondView = [UIView initWithFrame: secondFrame];
UIView* thirdView = [UIView initWithFrame: thirdFrame];

NSDictionary* aDictionary = [[NSDictionary dictionaryWithObjectsAndKeys:
  firstView, @"firstView",
  secondView, @"secondView",
  thirdView, @"thirdView", nil] retain];

Now, to look up a view (or any other object) by name, use this code:

Code:
UIView* viewFromString = [aDictionary objectForKey: @"firstView"];

Does that help?
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 05-29-2011, 11:54 AM   #5 (permalink)
Registered Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 3,858
smasher will become famous soon enough
Default

Use an NSMutableArray to hold your five mapviews. Looking up a variable by name is the wrong problem to solve - you're really trying to loop through a list of views, and an array is the right way to do that.
__________________

Free Games!
smasher is offline   Reply With Quote
Old 05-29-2011, 03:40 PM   #6 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Smile

Quote:
Originally Posted by Duncan C View Post
You're trying to look up an object by using a string which is the name of that object?

There's not really a way to do that.

The closest you can come is to put all the objects you want to look up by name into a dictionary:

Code:
UIView* firstView = [UIView initWithFrame: firstFrame];
UIView* secondView = [UIView initWithFrame: secondFrame];
UIView* thirdView = [UIView initWithFrame: thirdFrame];

NSDictionary* aDictionary = [[NSDictionary dictionaryWithObjectsAndKeys:
  firstView, @"firstView",
  secondView, @"secondView",
  thirdView, @"thirdView", nil] retain];

Now, to look up a view (or any other object) by name, use this code:

Code:
UIView* viewFromString = [aDictionary objectForKey: @"firstView"];

Does that help?
Thanks guys that's exactly what I was looking for! One quick question, can you tell me if I'm doing this right? I'm trying to add an image to one of the Main Views:

Code:
UIImage *image1 = [UIImage imageWithContentsOfFile:@"Graphic Elements/Map 1 Main Elements/1 Main Floating Cube.png"];
        UIImageView *map1MainView1 = [[UIImageView alloc] initWithImage:image1];
        [map1MainView addSubview:map1MainView1];
UnretroGamer is offline   Reply With Quote
Old 05-29-2011, 07:29 PM   #7 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
Join Date: Jan 2010
Location: Issaquah, WA
Age: 42
Posts: 1,244
dljeffery is on a distinguished road
Default

Quote:
Originally Posted by UnretroGamer View Post
Code:
for (int mainViewNumber = 1; mainViewNumber < 5; mainViewNumber++) {
        NSString *mainViewName = [[NSString alloc] initWithFormat:@"map%dMainView", mainViewNumber];
        UIView *mainView = [[NSClassFromString(mainViewName) alloc] init];
        if (mainView == nil) {
            NSLog(mainViewName);
        }
        [cvMainViewScrollView insertSubview:mainView atIndex:mainViewNumber];
        mainView.center = CGPointMake(commandView.center.x + (mainView.frame.size.width * (mainViewNumber - 1)), commandView.center.y);
        NSString *log = [[NSString alloc] initWithFormat:@"Added %@ to mainview!", mainViewName];
        NSLog(log);
    }
Does a lot of your code look similar to this? You sure are leaking a lot of stuff there... mainViewName, mainView and log. Plus you're really going out of your way to leak your log string. NSLog was intended to be a one-step operation; it takes a format string plus as many arguments as you need.
__________________
Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

Recall It! for iPad

http://www.dljeffery.com
dljeffery is offline   Reply With Quote
Old 05-29-2011, 09:21 PM   #8 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Default

Quote:
Originally Posted by dljeffery View Post
Does a lot of your code look similar to this? You sure are leaking a lot of stuff there... mainViewName, mainView and log. Plus you're really going out of your way to leak your log string. NSLog was intended to be a one-step operation; it takes a format string plus as many arguments as you need.
I'm pretty new, honestly I didn't *really* know what leaking is until you posted this. So I'm assuming leaking is when you allocate something and don't release it?

Anyways I'm a little deep into my project, I'm pretty sure I can add all the releases later.

P.S. I found what was wrong with the Image loading thing, I had to use imageNamed instead of initWithContentsOfFile.
UnretroGamer is offline   Reply With Quote
Old 05-30-2011, 06:51 AM   #9 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by UnretroGamer View Post
I'm pretty new, honestly I didn't *really* know what leaking is until you posted this. So I'm assuming leaking is when you allocate something and don't release it?

Anyways I'm a little deep into my project, I'm pretty sure I can add all the releases later.

P.S. I found what was wrong with the Image loading thing, I had to use imageNamed instead of initWithContentsOfFile.
Memory management is perhaps the single most important thing to get right about Cocoa development. If you don't learn the rules of memory management and apply them religiously, your apps will be buggy and subject to unexpected crashes. You will get very frustrated and decide that iOS programming is impossible.

I urge you to stop now, read the memory management programming guide, and don't write another line of code until you understand the rules and can follow them consistently. Writing a bunch of code and waiting to "add the releases later" is a big, big mistake. It's like building a concrete bridge and assuming you can add the steel reinforcement later. You'll be too busy dealing with collapsing structures to have time to fix everything. Really.

The good news is that the rules of Cocoa memory management are actually quite simple. I suggest you read this:

Loading…

In particular, read the section "Memory Management Rules"
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 05-30-2011, 05:47 PM   #10 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Default

Thanks for the advice. I didn't understand it the first time I read it (when I had JUST wanted to start programming) but I'll read it again now. Hopefully it'll make more sense to me now.
UnretroGamer is offline   Reply With Quote
Old 05-30-2011, 05:51 PM   #11 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Default

Oh yeah, I have lots of strings like this:
Code:
NSLog([[NSString alloc] initWithFormat:@"Inserted %@ in cvMainViewScrollView at index %d!", mainViewName, mainViewNumber]);
How would I release that?

UPDATE: I have a few questions you can hopefully answer:
1) The last question
2) Is "release" the only thing I need to know? Should I look into what dealloc is? What's the difference?
3) If I tell the app delegate to switch rootviewcontroller, does it release everything from the last rootviewcontroller? if not, under what method should I put all my releases?
4) If I switch views using the [UIView transitionFromView:toView:duration: ...] does it release everything from the last view?
5) How do I remove/release a specific subview?

UPDATE 2: Yeah I tried turning all those strings into something like this:
Code:
NSLog([NSString initWithFormat:@"Inserted %@ in cvMainViewScrollView at index %d!", mainViewName, mainViewNumber]);
and nothing works now, it seems I have to allocate it. I just don't know how to release it cause it has no name.

UPDATE 3: Changed all those initWithFormats to stringWithFormats. Problem solved.
Object Ownership and Disposal = very useful information. Thanks.

Last edited by UnretroGamer; 05-30-2011 at 06:24 PM. Reason: UPDATE 3
UnretroGamer is offline   Reply With Quote
Old 05-30-2011, 06:33 PM   #12 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by UnretroGamer View Post
Oh yeah, I have lots of strings like this:
Code:
NSLog([[NSString alloc] initWithFormat:@"Inserted %@ in cvMainViewScrollView at index %d!", mainViewName, mainViewNumber]);
How would I release that?
The way you've written it, you can't. You're creating an object with alloc/init and not saving a pointer to it, so there's no way to release it.

NSLog takes a format string and parameters. You should rewrite it like this:

Code:
NSLog(@"Inserted %@ in cvMainViewScrollView at index %d!"", mainViewName, mainViewNumber);
Actually, you could set up your string to be released later, by using autorelease. The method autorelease tells the system to send your object a release message after this pass through the event loop. The object will stick around until your code returns, and then get its release message once your code is done. You'd just enclose your alloc/init call in another set of brackets, with "autorelease" before the last closing bracket. However, don't do that. As I said, NSLog is written to take a format string and a variable number of parameters. Use that feature instead of creating a new string.

Quote:
UPDATE: I have a few questions you can hopefully answer:
1) The last question
2) Is "release" the only thing I need to know? Should I look into what dealloc is? What's the difference?
All this is covered in the memory management guide, and explained better than I can explain it.

retain and release are opposites. They cause an object's retain count to be increased by one / decreased by 1.

An object can have more than one owner. The retain count is used to keep track of how many owners an object has. When an object's retain count drops to zero, it gets deallocated (That means its memory is freed and it goes away.)


autorelease, as I mentioned above, is a variant of release that adds your object to a list of objects that will get a release message once your code returns. It's useful for creating temporary objects and forgetting about them. Many of the system methods like the NSString stringWithFormat method return autoreleased objects. They stick around until your code returns, and then get discarded unless somebody else sends them a retain message.

An object's dealloc method gets called right before the object is freed (taken out back and shot.) It's the object's chance for a final cigarette - or rather, an object's chance to do cleanup, and send release messages to any objects that it owns.

3) If I tell the app delegate to switch rootviewcontroller, does it release everything from the last rootviewcontroller? if not, under what method should I put all my releases?

You can't change root view controllers. The root view controller of a navigation controller is fixed, at least as far as I know.

Quote:
4) If I switch views using the [UIView transitionFromView: toView:duration: ...] does it release everything from the last view?
I haven't used that method before. My company's apps to date have been written to work on iOS 3.2 or later, and that method requires 4.0. I'm honestly not sure if it removes the old view from it's superview. This bit from the documentation makes it sound like the old view is removed from it's superview (and thus released) at the end of the animation:

Code:
"By default, the view in fromView is replaced in the view hierarchy by the view in toView"
Usually, views are retained by their parent view (or "superview") The outermost view is retained by the view controller. When the view controller is released, it releases it's content view. The content view releases it's sub-views, which in turn release their sub-views

Quote:
5) How do I remove/release a specific subview?
You can send a view a -removeFromSuperview message. That causes it to be removed from it's parent view. The parent view sends it a release, which causes it to be deallocated unless somebody else has also retained it.

Get yourself a book on Cocoa programming and read it. I'm about tapped out answering questions that are really well documented by Apple and well described in dozens of books.
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 05-30-2011, 06:51 PM   #13 (permalink)
Just Some Guy
 
Join Date: Dec 2010
Posts: 112
UnretroGamer is on a distinguished road
Default

I'm sorry your tired of it. I bought two $50 books that haven't helped nearly as much as this forum (half of the questions answered specifically by you). I hope my questions will get more advanced and interesting for you in the future. Anyways, you've been a huge help! Thanks for all the advice and solutions.

P.S. You can switch root view controllers. Tell the App Delegate to do this:
Code:
- (void)switchTo<name of view controller> {
    self.window.rootViewController = <view controller>;
    [self.window makeKeyAndVisible];
}
after having linked the view controller to the App Delegate in the MainWindow nib. ;]
UnretroGamer is offline   Reply With Quote
Reply

Bookmarks

Tags
addsubview, fromstring, nsstring, uiview

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 339
6 members and 333 guests
Dnnake, dre, iOS.Lover, jenniead38, Kirkout, Wikiboo
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,663
Threads: 94,120
Posts: 402,898
Top Poster: BrianSlick (7,990)
Welcome to our newest member, LezB44
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:16 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0