简体   繁体   中英

Alloc and init NSArrays inside or outside a parsing function in Objective-C?

Im trying to understand WHERE is better to allocate my arrays, in a Objective-C ARC application:

CASE 1 : alloc and init arrays outside parsing function

- (void)viewDidLoad { // or another method

    // other code
    // here I alloc and init arrays:

    dataSource2 = [[NSMutableArray alloc] init]; 
    dataSource3 = [[NSMutableArray alloc] init]; 
    dataSource4 = [[NSMutableArray alloc] init]; 
    dataSource5 = [[NSMutableArray alloc] init]; 
    dataSource6 = [[NSMutableArray alloc] init]; 
    dataSource7 = [[NSMutableArray alloc] init]; 
    dataSource8 = [[NSMutableArray alloc] init]; 
    dataSource9 = [[NSMutableArray alloc] init]; 
}

- (void)parseFunction {

    // parsing code
    // do something with arrays and iterate, example: 

       for (int i = 1; i < [arrays count]; ++i) {
            [dataSource2 addObject:object2];
            [dataSource3 addObject:object3];
            [dataSource4 addObject:object4];
            [dataSource5 addObject:object5];
            [dataSource6 addObject:object6];
            [dataSource7 addObject:object7];
            [dataSource8 addObject:object8];
            [dataSource9 addObject:object9];
        }
}

CASE 2 : alloc and init arrays inside parsing function and outside iteration cycle

- (void)viewDidLoad { // or another method

    // other code
}

- (void)parseFunction {

    // here I alloc and init arrays: 

    dataSource2 = [[NSMutableArray alloc] init]; 
    dataSource3 = [[NSMutableArray alloc] init]; 
    dataSource4 = [[NSMutableArray alloc] init]; 
    dataSource5 = [[NSMutableArray alloc] init]; 
    dataSource6 = [[NSMutableArray alloc] init]; 
    dataSource7 = [[NSMutableArray alloc] init]; 
    dataSource8 = [[NSMutableArray alloc] init]; 
    dataSource9 = [[NSMutableArray alloc] init]; 

    // parsing code
    // do something with arrays and iterate, example:

       for (int i = 1; i < [arrays count]; ++i) {

            [dataSource2 addObject:object2];
            [dataSource3 addObject:object3];
            [dataSource4 addObject:object4];
            [dataSource5 addObject:object5];
            [dataSource6 addObject:object6];
            [dataSource7 addObject:object7];
            [dataSource8 addObject:object8];
            [dataSource9 addObject:object9];
        }
}

CASE 3 : alloc and init arrays inside parsing function and inside iteration cycle

- (void)viewDidLoad { // or another method

    // other code
}

- (void)parseFunction {

    // parsing code, alloc init and iterate, all in the same cycle:

       for (int i = 1; i < [arrays count]; ++i) {

       dataSource2 = [[NSMutableArray alloc] init]; 
       dataSource3 = [[NSMutableArray alloc] init]; 
       dataSource4 = [[NSMutableArray alloc] init]; 
       dataSource5 = [[NSMutableArray alloc] init]; 
       dataSource6 = [[NSMutableArray alloc] init]; 
       dataSource7 = [[NSMutableArray alloc] init]; 
       dataSource8 = [[NSMutableArray alloc] init]; 
       dataSource9 = [[NSMutableArray alloc] init]; 

            [dataSource2 addObject:object2];
            [dataSource3 addObject:object3];
            [dataSource4 addObject:object4];
            [dataSource5 addObject:object5];
            [dataSource6 addObject:object6];
            [dataSource7 addObject:object7];
            [dataSource8 addObject:object8];
            [dataSource9 addObject:object9];
        }
}

Well, my application works without crashes in all 3 cases, but I'd like to read an explanation of where should I allocate a great number of arrays: is it the same thing? or is there a BEST position, in terms of performance and memory allocation, to avoid some issues? Thanks!

3rd is Incorrect. You are creating / allocating all the arrays multiple times and storing only last one.

1st and 2nd are quite good. It depends on your requirement. If you are sure that these array will only be required only once when you call the method and not else where. Then 2 is fine. But if you call it twice then it will be like 3.

However all properties are initialized in viewDidLoad method.

CASE 3:

utterly incorrect: at each iteration you are "resetting" the arrays content; at the end of the loop, your arrays will only contain the last element you added;

CASE 1:

you initialize you arrays once in your view lifetime; then each time you execute the parse function you are adding new elements to those same arrays; the arrays will grow larger and larger as you keep calling the parse method and will contain, say, the "history" of all your parsing;

CASE 2:

each time you enter the parse function, you "reset" the arrays, then fill them up with new elements; at the end of the loop the arrays will only contain the results of the last parse task.

So, between 1 and 2, it depends on what you are trying to do; both things can make sense, and I would bet for 2.

EDIT:

In reply to your other question (comments):

Thank you @sergio, until now your's is the best explanation; but what is the danger and issue of allocating and initialing arrays INSIDE a ViewController?

I would not talk of danger or issues: it can work perfectly fine, at least for simple apps.

On the other hand, imagine you want to display the content you parse in a 2-level view: first a list of items (imagine a table); then, when you select one item, you move to another view displaying some more details about that item.

In this case, you would have 2 different controllers requiring access to the same data. If you array is managed by just one controller, then the other is made dependent on this. And the thing could become more complex if you add more controllers and views accessing the same data.

Thus, it is a question of "good design" and being prepared for change: if you make your data managed through and ad-hoc class (the model in model-view-controller), you get a much cleaner and orderly graph of dependencies.

Hope this helps.

As the others said, the third option is completely wrong. But the other two options are not very good either. You really should not have your data model and parsing code in a view controller. Create one class to handle your data model in which you do all the parsing and pass that to your view controller, for example in your init method. Don't have your view controller create that data model object.

Read about the Single Responsibility Principle and Dependency Injection .

Or you can manage to do all of these things in array of dictionaries then you don't have to keep track of N datasource arrays:

You can do is:

MasterArray -> Holding Keys of All sub arrays -> Add sub arrays data on a key. and dealloc these subarrays dynamically, so in memory you will only have one masterArray but not N datasource arrays.

Eg:

MasterArray { '0' = ( { some array Objects ) };

'1' = ( { some array Objects ) };

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM