在Objective-C中解析函数内部或外部的Alloc和init NSArrays?

时间:2022-09-07 11:21:18

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

我试图在Objective-C ARC应用程序中理解WHERE更好地分配我的数组:

CASE 1: alloc and init arrays outside parsing function

情况1:解析函数外的alloc和init数组

- (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

情况2:解析函数和外部迭代周期内的alloc和init数组

- (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

情况3:在解析函数内部和迭代周期内的alloc和init数组

- (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!

好吧,我的应用程序在所有3种情况下都没有崩溃,但是我想阅读一个解释,我应该在哪里分配大量的数组:它是一样的吗?或者在性能和内存分配方面是否存在最佳位置以避免某些问题?谢谢!

4 个解决方案

#1


1  

CASE 3:

案例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:

情况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;

在视图生命周期中初始化一次数组;然后每次执行解析函数时,都会向这些相同的数组添加新元素;当你继续调用parse方法时,数组会变得越来越大,并且包含所有解析的“历史”;

CASE 2:

案例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.

所以,1到2之间,这取决于你想要做什么;这两件事都有意义,我敢打赌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?

谢谢你@sergio,直到现在你的是最好的解释;但是在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.

另一方面,想象一下您想要在2级视图中显示您解析的内容:首先是项目列表(想象一个表格);然后,当您选择一个项目时,您将移动到另一个视图,显示有关该项目的更多详细信息。

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.

在这种情况下,您将有2个不同的控制器需要访问相同的数据。如果您的阵列仅由一个控制器管理,则另一个控制器依赖于此。如果添加更多控制器和访问相同数据的视图,事情可能会变得更加复杂。

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.

因此,这是一个“良好设计”的问题,并为变革做好准备:如果您通过ad-hoc类(模型 - 视图 - 控制器中的模型)管理数据,您将获得更清晰,有序的依赖图。

Hope this helps.

希望这可以帮助。

#2


2  

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.

第一和第二都很好。这取决于您的要求。如果您确定在调用方法时只需要一次这些数组,而不是其他地方。然后2很好。但是,如果你把它叫两次,那就像3。

However all properties are initialized in viewDidLoad method.

但是,所有属性都在viewDidLoad方法中初始化。

#3


1  

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.

正如其他人所说,第三种选择是完全错误的。但其他两个选项也不是很好。你真的不应该在视图控制器中拥有数据模型和解析代码。创建一个类来处理您进行所有解析的数据模型,并将其传递给视图控制器,例如在init方法中。没有视图控制器创建该数据模型对象。

Read about the Single Responsibility Principle and Dependency Injection.

阅读单一责任原则和依赖注入。

#4


0  

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:

或者您可以设法在字典数组中执行所有这些操作,然后您不必跟踪N个数据源数组:

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.

MasterArray - >保持所有子阵列的键 - >在键上添加子阵列数据。并动态地释放这些子数组,因此在内存中只有一个masterArray而不是N个数据源数组。

Eg:

例如:

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

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

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

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

Hope it helps.

希望能帮助到你。

#1


1  

CASE 3:

案例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:

情况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;

在视图生命周期中初始化一次数组;然后每次执行解析函数时,都会向这些相同的数组添加新元素;当你继续调用parse方法时,数组会变得越来越大,并且包含所有解析的“历史”;

CASE 2:

案例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.

所以,1到2之间,这取决于你想要做什么;这两件事都有意义,我敢打赌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?

谢谢你@sergio,直到现在你的是最好的解释;但是在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.

另一方面,想象一下您想要在2级视图中显示您解析的内容:首先是项目列表(想象一个表格);然后,当您选择一个项目时,您将移动到另一个视图,显示有关该项目的更多详细信息。

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.

在这种情况下,您将有2个不同的控制器需要访问相同的数据。如果您的阵列仅由一个控制器管理,则另一个控制器依赖于此。如果添加更多控制器和访问相同数据的视图,事情可能会变得更加复杂。

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.

因此,这是一个“良好设计”的问题,并为变革做好准备:如果您通过ad-hoc类(模型 - 视图 - 控制器中的模型)管理数据,您将获得更清晰,有序的依赖图。

Hope this helps.

希望这可以帮助。

#2


2  

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.

第一和第二都很好。这取决于您的要求。如果您确定在调用方法时只需要一次这些数组,而不是其他地方。然后2很好。但是,如果你把它叫两次,那就像3。

However all properties are initialized in viewDidLoad method.

但是,所有属性都在viewDidLoad方法中初始化。

#3


1  

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.

正如其他人所说,第三种选择是完全错误的。但其他两个选项也不是很好。你真的不应该在视图控制器中拥有数据模型和解析代码。创建一个类来处理您进行所有解析的数据模型,并将其传递给视图控制器,例如在init方法中。没有视图控制器创建该数据模型对象。

Read about the Single Responsibility Principle and Dependency Injection.

阅读单一责任原则和依赖注入。

#4


0  

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:

或者您可以设法在字典数组中执行所有这些操作,然后您不必跟踪N个数据源数组:

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.

MasterArray - >保持所有子阵列的键 - >在键上添加子阵列数据。并动态地释放这些子数组,因此在内存中只有一个masterArray而不是N个数据源数组。

Eg:

例如:

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

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

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

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

Hope it helps.

希望能帮助到你。