2

I am working on an iPhone app that requires sequential flow in order for me to capitalize on user-friendly handling. The application is one large loop of multiple view controllers, where a user advances through the various modules of the app. I have an internal loop within the main application loop that consists of just 2 of the view controllers, and concludes whenever the user decides to proceed onward.

The internal 2-controller loop is what I am targeting with my question. It consists of a table view controller (apply change to the user's selection) and a detail view controller (display the changes). Currently, my issue is with increasing memory usage every time the loop proceeds to one of the view controllers. I've heard that forward class declaration is a good way to handle circular dependencies (2-controller loop), but I haven't seen any working example that applies to my situation. Can forward class declaration be used in my case to effectively loop multiple view controllers, and if so how can I do it?

Below is an example of what I'm thinking I need to employ. Is this reasonable? (I am very new to objective-c and the forward declaration concept)

TableViewController.h

#import <UIKit/UIKit.h>

@class detailViewController;

@interface TableViewController : UITableViewController
{
    // Stuff for TableViewController object
}

@end

detailViewController.h

#import <UIKit/UIKit.h>

@class TableViewController

@interface detailViewController : UIViewController
{
    // Stuff for detailViewController object
}

@end
Pholotic
  • 73
  • 7
  • 2
    I agree with Ben-G that this has nothing to do with circular dependency. How are you "cycling" between the two view controllers? Are you pushing each one into a Navigation Controller? If so, every view controller you've created is being stored, increasing memory usage. – Josh at The Nerdery Aug 12 '14 at 17:45
  • That is unfortunately what is happening. Memory usage keeps increasing as more views are pushed onto the navigation controller. I want to avoid this behavior. – Pholotic Aug 12 '14 at 22:26
  • TO ALL: I'm saying in my question that CURRENTLY my application has memory issues, where memory usage continues to grow as I advance view controllers within a loop using navigation controller. It is that I am wondering whether or not forward class declaration might be an alternative approach to a problem with looped view controllers, and if so then how could it be implemented. NOTE: I am very unfamiliar with these concepts, especially with implementing them in iOS mobile app design. I get that I may not have explained my issue perfectly... cut me some slack – Pholotic Aug 13 '14 at 04:05
  • Say pholotic - it occurs to me your "actual" problem may be that your'e struggling with setting up your container views properly. Here's a long thing on that issue .. http://stackoverflow.com/a/23403979/294884 (a bit out of date since you're Swift now...) – Fattie Aug 13 '14 at 08:13
  • That's a lot to digest. I haven't used "container views" before. I have been working with setting up view controllers which I've been segueing to. App development has sadly become a huge mess for me since I've been trying to learn how to run before I can even walk. Thanks for sharing that link. – Pholotic Aug 13 '14 at 12:45

3 Answers3

0

I'm not 100% I understand the structure of your project, but here are some hints I can give you:

You are discussing two different problems.

Retain Cycles

Retain Cycles can cause memory issues in your program. When you are facing a memory issue in your app (and are using ARC) the changes are high that you have created a retain cycle. This means that two objects in your code each reference each other through a strong relationship. That will cause both objects to stay in memory forever. In your application it seems likely that the TableViewController and the DetailViewController are referencing each other strongly. If you only want to pass information from one ViewController to another, you should use a weak reference:

@property (weak) DetailViewController *detailViewController;

Circular Dependencies

Circular Dependencies occur when two Classes try to import each others header. If Class A imports Class B in its header and Class B imports Class A in its header you will have a unresolvable circular dependency because the preprocessor will not know how to import Header files that depend on each other. This is resolved by using forward declarations instead of import statements. But this has nothing to do with memory management. Basically you should be using forward declarations whenever it is possible (when you only need to know that a certain class exists) and only use #import statements when it's actually necessary to know details about the interface of that class (subclassing, accessing properties of other Classes in .m files).

Ben-G
  • 4,896
  • 25
  • 33
0

Your .h file is just a public interface. Without inclusion into your .h file, you can still have members of view controllers visible to each other, while oblivious to other classes.

If no public data members are dependent upon another View Controller, you can consider including one view controller .h file inside another one's .m file, instead of it's .h file. That way, circular dependency can be avoided.

As you know, you can declare private data members within .m file as well, after @interface keyword. Like this:

2.m:

#import 1.h

@interface 2
{

}

1.m:

#import 2.h
@interface 1
{

}

Even removing from either .h the reference to another .h file may solve the circular dependency problem.

Having said that, circular dependency is something you need to handle at compile / build time, and it has nothing to do how you navigate between the two view controllers when your app runs.

Assuming that is your question, and you have a storyboard in front of you, you should consider:

1 - embedding your first view controller inside a Navigation controller

2 - create a push segue from first to second view controller. use performSegueUsingIdentifier to navigate from first to second VC.

3 - Similarly, you can use popViewController function to navigate from second to first.

None of these steps require you to deal with circular dependency, and you should read the documentation very thoroughly to understand what you want to achieve.

In short, RTFM.

Nirav Bhatt
  • 6,682
  • 5
  • 39
  • 82
  • 2
    The OP is confused. The question has nothing at all to do with forward declarations. – rmaddy Aug 12 '14 at 17:47
  • As stated in the post, "I am very new..." Hopefully this implies to others that, much more likely then not, I am confused. – Pholotic Aug 13 '14 at 04:17
-2

You know, I really think you're asking for nothing more than how to pop on and pop off a view controller. It's really trivial and it will solve all your problems. Check it out.

Just regarding putting "@class blah;" at the top of a file - yeah, whatever, do that. It's no big deal. If it's "not finding" a class, sure, just put it in.

As everyone has explained, you do not and should not think about "memory management" today in iPhone programming. It's irrelevant.

Fattie
  • 30,632
  • 54
  • 336
  • 607
  • 3
    Your last sentence couldn't be more wrong. Memory management is just as important today (using ARC) as ever. There's less to deal with but there are still plenty of memory issues you have to worry about. – rmaddy Aug 12 '14 at 18:38
  • I hope you're right, that this simply is a pop on / pop off issue. Will check into it, thanks. – Pholotic Aug 13 '14 at 04:30
  • not really, maddy - you have to program for ios today in such a way that "memory management is irrelevant". you can't use retain any more - you have to go with the new metaphors in iOS. if the OP is bizarrely using more and more memory, they are probably just endlessly creating views, rather than understanding you just pop them on and off. – Fattie Aug 13 '14 at 06:14
  • 3
    @JoeBlow When you program for iOS today, there is NO way that memory management is irrelevant. You still have to worry about reference cycles and autorelease pools. And if you use any of the "CF" type functions, or low level memory like `malloc`, you have to worry about releasing and freeing that memory too. BTW - when you reply to someone, be sure to precede their actual username with an "@" sign. You used the wrong username and no "@" sign. I only saw your reply by chance. – rmaddy Aug 13 '14 at 07:17
  • Thanks Joe Blow, you seemed to have aptly pointed out my issue. The behavior I believe to be best for my application is a cycle between views: view1 then view2 then view1 ... etc, advancing by a "next" button. However, the views are endlessly being created, stacking tons of memory usage. The way I see it is that I only need one of each view (just bounce back and forth between the two) since the only dynamic property being shared and updated between the views is a UIImage. Does this further detail fit better with your suggestion? – Pholotic Aug 13 '14 at 12:19
  • Sounds like we're on the same page. I have no experience with methods for replacing views. I have always just segued my way to what I'm looking for, inevitably using memory and simply not thinking much of it. Might you happen to know any SO links off the top of your head that pertain to effective replacement or view management methods? – Pholotic Aug 13 '14 at 12:58