Użycie alloc INIT zamiast new

Ucząc się Objective-C i czytając przykładowy kod, zauważam, że obiekty są zwykle tworzone za pomocą tej metody:

SomeObject *myObject = [[SomeObject alloc] init];

Zamiast:

SomeObject *myObject = [SomeObject new];

Czy jest ku temu jakiś powód, ponieważ czytałem, że są one równoważne?

Author: Qantas 94 Heavy, 2009-04-06

8 answers

Jest tu kilka powodów: http://macresearch.org/difference-between-alloc-init-and-new

Niektóre wybrane to:

  • new nie obsługuje niestandardowych inicjalizatorów (takich jak initWithString)
  • alloc-init jest bardziej jednoznaczne niż new

Ogólna opinia wydaje się być taka, że powinieneś używać tego, co Ci odpowiada.

 273
Author: Jeremy Stanley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 20:34:24

Bardzo stare pytanie, ale napisałem jakiś przykład tylko dla zabawy-może się przyda;)

#import "InitAllocNewTest.h"

@implementation InitAllocNewTest

+(id)alloc{
    NSLog(@"Allocating...");
    return [super alloc];
}

-(id)init{
    NSLog(@"Initializing...");
    return [super init];
}

@end

W funkcji głównej oba wyrażenia:

[[InitAllocNewTest alloc] init];

I

[InitAllocNewTest new];

Wynik w tym samym wyniku:

2013-03-06 16:45:44.125 XMLTest[18370:207] Allocating...
2013-03-06 16:45:44.128 XMLTest[18370:207] Initializing...
 133
Author: guitar_freak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 20:35:40

+new jest odpowiednikiem +alloc/-init w implementacji Apple NSObject. Jest bardzo mało prawdopodobne, że to się kiedykolwiek zmieni, ale w zależności od Twojego poziomu paranoi, dokumentacja Apple dla +new wydaje się pozwalać na zmianę implementacji (i złamanie równoważności) w przyszłości. Z tego powodu, ponieważ "explicit is better than implicit" i dla ciągłości historycznej, Wspólnota Objective-C generalnie unika +new. Można jednak zazwyczaj zauważyć najnowsze Java comers do Objective-C przez ich użycie +new.

 51
Author: Barry Wark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-06 02:21:45

Często będziesz musiał przekazać argumenty do init, więc będziesz używał innej metody, takiej jak [[SomeObject alloc] initWithString: @"Foo"]. Jeśli jesteś przyzwyczajony do pisania tego, masz w zwyczaju robić to w ten sposób i tak [[SomeObject alloc] init] może przyjść bardziej naturalnie, że [SomeObject new].

 8
Author: Brian Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-05 23:52:07

Jedna krótka odpowiedź brzmi:

  1. Oba są takie same. Ale
  2. 'new' działa tylko z podstawowym 'INIT' i nie będzie praca z innymi inicjalizatorami (np. initWithString:).
 7
Author: user739711,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-02 04:22:26

Na marginesie, ja osobiście używam [Foo new], jeśli chcę, aby coś w init zostało zrobione bez użycia jego zwracanej wartości gdziekolwiek. Jeśli nigdzie nie użyjesz zwrotu [[Foo alloc] init], otrzymasz ostrzeżenie. Mniej więcej, używam [Foo new] do eye candy.

 3
Author: evdude100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-04 13:44:53

Jestem na to bardzo spóźniony, ale chcę wspomnieć, że ta nowa jest w rzeczywistości niebezpieczna w Obj - C ze Swift world. Swift utworzy domyślną metodę init tylko wtedy, gdy nie utworzysz żadnego innego inicjalizatora. Wywołanie nowego w klasie swift z niestandardowym inicjalizatorem spowoduje awarię. Jeśli użyjesz alloc/INIT, kompilator będzie prawidłowo narzekał, że init nie istnieje.

 3
Author: MurderDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-29 00:50:05

Jeśli new wykona zadanie za Ciebie, wtedy twój kod również będzie skromnie mniejszy. Jeśli w przeciwnym razie wywołasz [[SomeClass alloc] init] w wielu różnych miejscach kodu, utworzysz Hot Spot w implementacji new - to znaczy w środowisku uruchomieniowym objc-który zmniejszy liczbę braków w pamięci podręcznej.

W moim rozumieniu, jeśli chcesz użyć niestandardowego inicjalizatora, użyj [[SomeClass alloc] initCustom].

Jeśli nie, Użyj [SomeClass new].

 1
Author: Mike Crawford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-01 14:38:53