Odpowiedz na ten temat
Pokaż wyniki od 1 do 9 z 9
  1. uho
    Mężczyzna uho jest offline
    Avatar uho
    Dołączył
    Mar 2008
    Skąd
    Łuków, PL
    Postów
    135

    Cytuj | #1

    witam, jeśli mam metodę klasową (klasy DataFromDB zwracającą np. NSMutableArray w której inicjuje obiekt NSMutableArray, aby za pomocą jego instancyjnych metod utworzyć tabele z obiektami, to kiedy należy zrobić release dla utworzonego obiektu, który musi być zwrócony za pomocą return ?

    przykładowo, to moja metoda klasowa:
    Kod:
    NSMutableArray *months = nil;
    + (NSMutableArray *)months
    {
    	months = [[NSMutableArray alloc] init];
    	
    	FMDatabase *db = [FMDatabase databaseWithPath:[self dbFilePath]];
    	[db open];
    	FMResultSet *rs = [db executeQuery:@"SELECT DISTINCT month FROM xxxx ORDER BY date DESC"];
    	while ([rs next]) {
    		[months addObject:[rs stringForColumn:@"month"]];
    	}
    	[rs close];
    	[db close];
    
    	return months;
    }
    a to jej użycie w innej klasie:

    Kod:
    NSMutableArray *monthsFromDB = [DataFromDB months];
    w którym miejscu powinienem użyć release dla utworzonej tabeli ?
    Telefon: iPhone 4S 16GB
    Odtwarzacz: iPod Nano 4G
    Tablet: iPad2 3G 16G
    WWW: http://www.tomaszbuziak.com


  2. Avatar danteusz
    Dołączył
    Jun 2009
    Skąd
    Wrocław-Psie Pole, Wroclaw, Poland, Poland
    Postów
    450

    Cytuj | #2

    Ja w takiej sytuacji daję autorelease w returnie, ale nie dam głowy za poprawność takiego rozwiązania
    Komputer: Macbook Pro '11 15 cali
    Telefon: iPhone 3GS

  3. uho
    Mężczyzna uho jest offline
    Avatar uho
    Dołączył
    Mar 2008
    Skąd
    Łuków, PL
    Postów
    135

    Cytuj | #3

    thx, dobry pomysł
    Telefon: iPhone 4S 16GB
    Odtwarzacz: iPod Nano 4G
    Tablet: iPad2 3G 16G
    WWW: http://www.tomaszbuziak.com


  4. Dołączył
    Feb 2010
    Postów
    222

    Cytuj | #4

    Pamiętaj, że retain'ować możesz dowoli, ale aby obiekt został zwolniony, musisz zrobić release tyle razy ile zrobiłeś retain i ani razu więcej, bo będzie błąd.

    Najłatwiej jest zrobić obiekt autorelease, jednak może on zniknąć (choć nie musi!) w trakcie wykonywania programu, nawet jeśli jakaś klasa przypisze go sobie do wskaźnika. Dlatego warto retainować obiekty, które będą używane przez dłuższy czas.

    Aby uniknąć problemów ze zwalnianiem, można zrobić też coś takiego:

    if (obiekt != nil) [obiekt release];

    Co w pewnym stopniu nas zabezpieczy przed próbą wywołania metody na nieistniejącym już obiekcie.

    Najwięcej błędów podczas pisania aplikacji wynika z niewłaściwego retainowania obiektów. Może być tak, że obiekt z autorelease będzie dostępny jeszcze przez kilka minut, a może się też zdarzyć, że zniknie po kilku sekundach. Ciężko się debuguje takie rzeczy, bo trudno o powtarzalne generowanie błędów.
    Moje aplikacje w AppStore:
    Blicks.

  5. Avatar Roberto
    Dołączył
    Feb 2007
    Skąd
    Wrocław
    Postów
    11,859

    Cytuj | #5

    sprawdzanie czy obiekt != nil jest zupełnie niepotrzebne przecież.
    w Obj-C jak najbardziej można wysyłać wiadomości do nil'a i nic złego się nie stanie. bo w sumie nic się nie stanie. program się przecież nie wywali.
    dlatego też warto nil'ować elementy po release.

    memory management to podstawa Obj-C bez której jest trudno.
    ale zasady są przecież bardzo proste - new, alloc, copy, init, new -> retain count = 1
    wszystko inne - samemu trzeba zrobić retain, jeżeli chce się mieć obiekt na dłużej (jeżeli to będzie w zakresie jednej metody to nie ma potrzeby raczej)
    przestajesz używać, a zaznaczyłeś że jest potrzebny (czyli stworzony przez metody z tymi słowami kluczowymi) - to release.
    jak się będzie trzymać tej konwekcji to wszystko będzie ok.

    autorelease służy właśnie do tego, z czym autor ma problem - stworzenia obiektu, którym ma zarządzać jakiś inny obiekt.

    więc w tej metodzie powinno być użyte autorelease
    a retain/release powinien być już robiony przez obiekt, który wywołał tę metodę.
    Komputer: MacBook Pro 13,3" 2,26GHz (Lion 10.7.3)
    Telefon: iPhone 4S
    Tablet: iPad 2 3G
    dlaczego nie korzystasz z opcji szukaj?
    http://ifiboughtyourappalreadycaniup...acappstore.com

  6. uho
    Mężczyzna uho jest offline
    Avatar uho
    Dołączył
    Mar 2008
    Skąd
    Łuków, PL
    Postów
    135

    Cytuj | #6

    Cytat Napisał Roberto Zobacz post
    więc w tej metodzie powinno być użyte autorelease
    a retain/release powinien być już robiony przez obiekt, który wywołał tę metodę.
    i tak właśnie postąpiłem, przecieki zniknęły, a program się nie wysypuje
    Telefon: iPhone 4S 16GB
    Odtwarzacz: iPod Nano 4G
    Tablet: iPad2 3G 16G
    WWW: http://www.tomaszbuziak.com

  7. Avatar wezuwiusz
    Dołączył
    Feb 2008
    Skąd
    Dublin, Katowice
    Postów
    783

    Cytuj | #7

    aktualny sposob na release obiektu zwracanego to: return [Object autorelease], jest w dokumentacji. Roberto, nie masz racji, wyslanie release do nieistniejacego obiektu wywola blad. sprawdz sobie wywolujac 2 x release do jakiegos obiektu (zakladajac ze jeko retain count = 1).
    Od iOS 5 juz nie trzeba sie bedzie wogole tym martwic bo zostal wprowadzony 'automatic reference couting', wiec mozna zapomniec wogole o retain, release... w zasadzie to jest funkcja kompilatora nie iOS-a wiec XCode 4.2 potrafi obsluzyc tez ARC dla projektow dla iOS 4.x (tylko trzeba recznie wlaczyc) dla nowych projektow jest to wlaczone automatycznie. tyle tylko ze trzeba troche pozmieniac w kodzie i zamiast @Property (...., assign/retain) nalezy uzywac weak/strong ...
    Komputer:  iMac 27"  iPhone4  iPad tv² +
    WWW: http://www.tridrops.com
    ____________________________/"'\,,, WezUwiUsz_
    Moja strona na FB
    Moje aplikacje: Easy Cash, Dock Clock, Flat Cube, Crazy Emoji

  8. Avatar Roberto
    Dołączył
    Feb 2007
    Skąd
    Wrocław
    Postów
    11,859

    Cytuj | #8

    wezuwiusz - mam rację, to Ty się teraz mylisz.
    nic nie pisałem o wysyłaniu release do nieistniejącego obiektu, pisałem o wysyłaniu (dowolnej) wiadomości do nil'a.
    Co możesz sobie samemu sprawdzić i przeczytać też w dokumentacji: Loading…

    jasne - wysyłanie wiadomości do miejsca w pamięci gdzie kiedyś był obiekt, ale ta pamięć została już zwolniona wywoła błąd.
    nie mniej - sprawdzanie czy obiekt != nil jest bez sensu.
    release nie powoduje nillowania
    a jeżeli obiekt jest nil'em - to nic się nie stanie przecież.
    to nie jest java, c++ czy coś w tym stylu przecież i czegoś takiego (sprawdzać, czy obiekt istnieje [czyli nie jest nil'em]) robić tutaj nie trzeba.

    sprawdź sobie sam:

    oczywiście tutaj wywalenie programu
    Kod:
    NSObject *object = [[NSObject alloc] init];
    [object release];
    [object release];
    i tutaj też oczywiście wywalenie programu, o co mi chodziło
    Kod:
    NSObject *object = [[NSObject alloc] init];
    [object release];
    if(object != nil)
    	[object release];
    brak jakiegokolwiek błędu, a o tym przecież pisałem.
    Kod:
    NSObject *object = [[NSObject alloc] init];
    [object release];
    object = nil;
    [object release];
    Komputer: MacBook Pro 13,3" 2,26GHz (Lion 10.7.3)
    Telefon: iPhone 4S
    Tablet: iPad 2 3G
    dlaczego nie korzystasz z opcji szukaj?
    http://ifiboughtyourappalreadycaniup...acappstore.com

  9. Avatar wezuwiusz
    Dołączył
    Feb 2008
    Skąd
    Dublin, Katowice
    Postów
    783

    Cytuj | #9

    @Roberto, ok. zrozumialem ze masz na mysli pierwszy przyklad...
    Komputer:  iMac 27"  iPhone4  iPad tv² +
    WWW: http://www.tridrops.com
    ____________________________/"'\,,, WezUwiUsz_
    Moja strona na FB
    Moje aplikacje: Easy Cash, Dock Clock, Flat Cube, Crazy Emoji

Odpowiedz na ten temat