Skocz do zawartości

Witaj!

Zaloguj lub Zarejestruj się aby uzyskać pełny dostęp do forum.

Zdjęcie
- - - - -

Przepisywanie zmiennych z jednej klasy do drugiej


  • Zaloguj się, aby dodać odpowiedź
24 odpowiedzi w tym temacie

#1 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 24 października 2010 - 22:04

Witam,
Na początku chcę tylko powiedzieć, że jeżeli nie jest to odpowiednie miejsce do zadawania banalnych pytań przez początkujących proszę mi tylko zwrócić uwagę, a przestane pisać. Na początku chyba każdy spotyka wiele trudności.

Nie wiem dlaczego, ale nie mogę przypisać wartości jednej klasy do drugiej. Program startuje jednak wiesza się jak tylko chcę kliknąć w jedną z komórek.
Oto fragment kodu:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Klub *nowyKlub = [[Klub alloc] init];
	NSUInteger row = [indexPath row];
	nowyKlub = [self.listaKlubow objectAtIndex:row];
	
	
	KartaKlubu *nowaKarta = [[KartaKlubu alloc] init];
 
	nowaKarta.nazwa = nowyKlub.nazwa;
	[self.navigationController pushViewController:nowaKarta animated:YES];
	[nowaKarta release];
	
	
	[tableView deselectRowAtIndexPath:indexPath animated:NO];
	
}
Błąd wywołuje na 99% linijka:
nowaKarta.nazwa = nowyKlub.nazwa;

Potrzebny jest jeszcze jakiś fragment kodu do analizy tego problemu?
Za odpowiedzi będę niezmiernie wdzięczny.
Pozdrawiam!

#2 macieks72

macieks72

  • 9 873 postów

Napisano 24 października 2010 - 22:13

Jaki błąd dokładnie?

#3 pyciu

pyciu
  • 28 postów

Napisano 24 października 2010 - 22:27

jak zdefiniowałeś zmienna nazwa w klasie KartaKlubu?

#4 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 24 października 2010 - 22:36

@interface KartaKlubu : UIViewController {
	
	NSString *nazwa;
}

@property(nonatomic, retain)NSString *nazwa;

W kolejnym pliku oczywiście @synthesize nazwa;.

Błąd jest taki, że, gdy np. wpiszę nowaKarta.nazwa = @"jfskldjfls"; Wszystko ładnie śmiga, ale jeżeli tylko spróbuje wpisać nowaKarta.nazwa = nowyKlub.nazwa, program mimo to, że ładnie się buduje i uruchamia, przy kliknięciu komórki w UITableView symulator się całkowicie wyłącza.

Pozdrawiam!

#5 wezuwiusz

wezuwiusz
  • 783 postów
  • SkądDublin, Katowice

Napisano 24 października 2010 - 22:38

sprawdz czy 'nazwa' jest mutable, jezeli to jest np. zwykly NSString to musisz go inaczej zainicjowac, albo [NSString stringWithString ... ] , albo '...stringWithFormat' itp. standartowy NSString nie jest mutable, czyli nie mozesz go zmieniac. jezeli 'nazwa' jest inna zmienna/obiektem to tez musi byc mutable. albo zmien w interface z NSString na NSMutablestring.

#6 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 24 października 2010 - 22:45

stara dobra zasada - stringi się kopiuje, a nie robi retain.
NSString property: copy or retain? - Stack Overflow

#7 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 25 października 2010 - 23:06

Sprawdziłem wasze wskazówki na moim projekcie i... Nic...
Gdy chce przypisać zmiennej wartość stringa którego przed chwilą stworzyłem:
NSString *string = [[NSString alloc] initWithFormat:@"Bla bla bla"];
 nowaKarta.nazwa = string;
...Wszystko działa normalnie.

Jeżeli tylko użyje zmiennej z innego obiektu np:
NSString *string = [[NSString alloc] initWithFormat:@"Bla bla bla %s",nowyKlub.nazwa];
 nowaKarta.nazwa = string;
... Wszystko się sypie...

Testowałem to na @property(nonatomic, copy) i (readwrite, copy)...

#8 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 25 października 2010 - 23:19

na 99% zwalniasz gdzieś obiekt za wcześnie. hasło: NSZombieEnabled poszukaj, włącz, popatrz sobie co ci wywala.

#9 wezuwiusz

wezuwiusz
  • 783 postów
  • SkądDublin, Katowice

Napisano 26 października 2010 - 00:44

1 - to co Roberto (NSZombieEnabled) i sprawdz czy na pewno cos tam jest i czy jest to na pewno string, najprosciej sobie lognij tego stringa 2 - a dlaczego uzywasz %s a nie %@ ? %s nie jest przypadkiem char ? chyba powinno sie uzywac %@ jako obiekt typu string... ?? zrob sobie testa np: if (![nowyKlub.nazwa isKindOfClass:[NSString class]] { nowaKarta.nazwa = [NSString stringWithString:nowyKlub.nazwa]; } else { nslog (@"nazwa nie jest stringiem"); } sprawdz po prostu czy nazwa na pewno jest obiektem/stringiem tu sie raczej dopatruj bledu. albo gdzies releasujesz 'nowyKlub' zbyt wczesnie ...

#10 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 26 października 2010 - 08:58

wezuwiusz - fakt. zły %s też spokojnie może doprowadzić do wywalenia programu. i to robi ;)

#11 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 26 października 2010 - 11:19

@Wezuwiusz Masz racje. Mój błąd. O ile pamiętam w C było tak że %c był na char'ów, a %s dla stringów, ale chyba się myliłem. Zmieniłem to i nie działa. Gdy dodaje ten "kod testowy" też wszystko siada jak wcześniej.

@Roberto Wieczorem jeszcze poczytam o tym NSZombieEnebled.

Nie zwalniam wcześniej chyba tego obiektu, bo tworzę go pare linijek wyżej. Oto kod. Może coś w nim zauważycie.
- (void)viewDidLoad {
	
	Klub *Heya = [[Klub alloc] init];
	
	Heya.nazwa = [[NSString alloc] initWithFormat: @"Heya Club"];
	Heya.adres = [[NSString alloc] initWithFormat:@"Dworcowa 23"];
	Klub *Pinokio = [[Klub alloc] init];
	Pinokio.adres = [[NSString alloc] initWithFormat:@"Bohaterów Warszawy 23"];
	Pinokio.nazwa = [[NSString alloc] initWithFormat: @"Pinokio"];
	Klub *City_Hall = [[Klub alloc] init];
	City_Hall.nazwa = [[NSString alloc] initWithFormat:@"City Hall"];
	City_Hall.adres = [[NSString alloc] initWithFormat:@"Gdzieś w piwnicy"]; 
	
	NSMutableArray *lista = [[NSMutableArray alloc] initWithObjects:Heya,Pinokio,City_Hall,nil];
	self.listaKlubow = lista;
	
	
	// usuwanie obiektow
	[lista release];
	[Heya release];
	[Pinokio release];
	[City_Hall release];
	
	
	
	
    [super viewDidLoad];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Klub *nowyKlub = [[Klub alloc] init];
	NSUInteger row = [indexPath row];
	nowyKlub = [self.listaKlubow objectAtIndex:row];
	
	NSString *string = [[NSString alloc] initWithFormat:@"bla %@", nowyKlub.nazwa];
	KartaKlubu *nowaKarta = [[KartaKlubu alloc] init]; 
	nowaKarta.nazwa= string;
	
	[self.navigationController pushViewController:nowaKarta animated:YES];
	
	[tableView deselectRowAtIndexPath: indexPath animated:NO]; 
	[nowaKarta release];
}

Dzięki Panowie za zainteresowanie.

#12 wezuwiusz

wezuwiusz
  • 783 postów
  • SkądDublin, Katowice

Napisano 26 października 2010 - 11:39

Rozumiem ze self.listaklubow jest retainowana ? Bo inaczej to ja zwalniasz zwalniając lista. Ale coś innego przykulo moja uwagę 'initwithformat' o ile się nie mylę to musisz podać format a nie tylko stringa, czyli ...initwithformat:@"%@" , @"Heyah Club"]. Juz pisaliśmy, sprawdź czy tworzysz prawidłowy string object. Bo moim zdaniem juz w tych linijkach initwithformat powinno ci wywalić, albo dać co najmniej warning.

#13 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 26 października 2010 - 14:13

ogólnie mi się ten kod ogólnie nie podoba po co tyle tych alokacji? init = 1 setter (geez nie cierpię notacji kropkowej w Obj-C) = +1, czyli 2 przy usuwaniu obiektów -1 czyli 1 i string zostaje w pamięci. zarządzanie pamięcią masz do powtórki, bo tutaj nawet ja widzę problemy.

#14 wezuwiusz

wezuwiusz
  • 783 postów
  • SkądDublin, Katowice

Napisano 26 października 2010 - 14:19

Roberto. no juz o kodzie nawet nie wspominam... wogole moglby zrobic wszystko w swojej klasie 'klub' ale zakladam ze po prostu zaczyna, wiec szkoda mu na razie glowe zawracac poprawnoscia kodu :) nauczy sie. do AppStore i tak tego nie wysle :) hehe od czegos musi zaczac.

#15 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 26 października 2010 - 14:44

wezuwiusz - a nie robi? ja tutaj widzę tylko że jest klub z 2 atrybutami, które ustawia (z nieznanych mi powodów) przy pomocy [[alloc] init]

Bananera - nie wiem jakie masz naleciałości z innych języków, nie wiem też jaka jest twoja wiedza z Obj-C.
zdajesz sobie sprawę że robiąc foo.bar = eglebegle tak naprawdę jest to [foo setBar:eglebegle] ?
potrafisz sam napisać settery/gettery? (IMO powinno się, jeżeli chce się korzystać z @property i @synthesize)
ogarniasz retain/release?
umiejętność zarządzania pamięcią jest tutaj niezbędna i na pewno nie jest to sprawa zbyt prosta.
+ przestawienia się na myślenie wyłącznie wskaźnikami tak naprawdę.

bo po kodzie wygląda jakbyś tego jeszcze nie ogarnął po prostu.
bo raczej każdy 'normalny' programista inicjując wartości przy pomocy setterów wstawia tam obiekty z autorelease (inaczej prowadzi to do takich sytuacji) jeżeli są to wartości dla tego tylko obiektu
po co robić
NSString *string = [[NSString alloc] initWithString:@"hello"];
[foo setBar:string];
[string release];

lepiej, ale nadal mało świadomie jest coś w stylu
NSString *string = [[[NSString alloc] initWithString:@"hello"] autorelease];
[foo setBar:string];

ale lepiej:
[foo setBar:[NSString stringWithString:@"hello"]];

a najwygodniej:
[foo setBar:@"hello"];

ogarnięcie retain, release, autorelese - niezbędne podstawy.
i nie wiem czy notacja kropkowa jest najlepsza dla początkujących...

#16 wezuwiusz

wezuwiusz
  • 783 postów
  • SkądDublin, Katowice

Napisano 26 października 2010 - 15:10

@Roberto, skrot myslowy :) mialem na mysli zeby zrobil metode np. [klub initWithname:name andAddress:addres] albo cos w tym stylu. ze juz o jakims arrayu lub dictionary nie wspomne :) no, namieszal troche, ale kazdy jakos kiedys zaczynal od 'hello world' - w sumie to bardziej bym Ci Bannera polecil wlasnie zaczecie od tego. I w sumie Roberto ma racje, dobrze by bylo zebys najpierw 'zalapal' gdzie i kiedy obiekt zyje. Mysle ze temat wyczerpany, musisz najpierw wiedziec czy Twoj NSString (adres/nazwa) jest prawidlowy. bo raczej tu jest blad.

#17 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 26 października 2010 - 15:30

@Wezuwiusz Tak. Jestem początkujący :) @Roberto i Wezuwiusz Dziękuje Panowie za wyczerpujące odpowiedzi. Na pewno mi pomogą. Postaram się jutro nad tym przysiąść, bo jestem dzisiaj zawalony. Jestem Wam winien piwo. Niezmierne dzięki! Arek

#18 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 26 października 2010 - 15:36

więc ja bym ci polecał tradycyjną ścieżkę ogarnięcie pisania swoich klas, setterów, getterów, inicjalizatorów, zobaczy jak gdzie i kiedy działają. potem bawienie się w @property i @sythesize w konsoli oczywiście, bez GUI jeszcze. prześledzenie właśnie życia obiektów, ogarnięcie jakoś retain/release, bo bez tego trudno iść dalej. to są podstawy, które trzeba umieć. retain/relese nie jest sprawą prostą i oczywistą. założenia są proste, ale sprawy się komplikują ;) warto nad tym na początku posiedzieć.

#19 wojtkow

wojtkow


  • 6 767 postów
  • Płeć:
  • SkądPoznań

Napisano 26 października 2010 - 18:05

@bananera - Poszukaj sobie książeczkę wydaną przez Helion (ale wydawnictwa O'Reilly) - Objective-C Leksykon kieszonkowy. Jest w niej dużo informacji nt. zarządzania pamięcią, ogólnie jest to dobry poradnik pozwalający zrozumieć bardzo specyficzny język jakim jest objC (specyficzny ale mnie bardzo odpowiadający).

#20 Bananera

Bananera
  • 216 postów
  • SkądSzczecin

Napisano 26 października 2010 - 20:38

@wojtkow Dzięki. Dzisiaj jeszcze zakupie w sklepie internetowych. @Roberto Kolejny raz... Dzięki :) Miłego wieczoru Panowie!

#21 macieks72

macieks72

  • 9 873 postów

Napisano 26 października 2010 - 20:40

W którym sklepie można kupić tę książeczkę? Wszystkie co przejrzałem to "brak tej pozycji" jest.

#22 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 26 października 2010 - 20:59

też swojego czasu szukałem mocno. w końcu jednak dorwałem Cocoa Programming for Mac OS X (przez Amazon UK, przez znajomych do pl. a teraz jest przesyłka za darmo z UK więc... warto) którą bardzo polecam :)

#23 wojtkow

wojtkow


  • 6 767 postów
  • Płeć:
  • SkądPoznań

Napisano 26 października 2010 - 22:17

Roberto - masz na myśli Aarona Hillegassa? Jeżeli tak to też dobra pozycja, można ją też kupić w Amazonie na Kindle (nie koniecznie mając Kindle, wystarczy aplikacja Kindle na dowolny system) - jest to notabene pierwsza pozycja którą kupiłem na Kindle :) Zaletą leksykonu jest jego zwartość. Niestety nie wiem gdzie go obecnie kupić. Ja mam pożyczony od kolegi :)

#24 JKK

JKK
  • 411 postów
  • SkądOsolin

Napisano 27 października 2010 - 06:48

Jak nie znajdziesz w sklepach (ja prawie rok temu już nie znalazłem) to pisz do wydawcy (Heliona) - mi przysłali dwie szt. z pod lady ;) Prawie nic z niej nie kumałem (ale ja poza tradycyjnym C nie znałem żadnego innego C ani języków obiektowych). Za to po 3 miesiącach walki z toturialami, google, stackoverflow itp. zaczęła się bardzo przydawać. Teraz też do niej zaglądam czasem.

#25 Roberto

Roberto
  • 13 752 postów
  • SkądWrocław

Napisano 27 października 2010 - 12:21

wojtkow - tak, dokładnie ta pozycja. nie cierpię czytać na ekranie komputera, a czytnik ebooków mi niepotrzebny ;) potrzebuję papier, bo inaczej biorę się jak pies do jeża ;) JKK - hm, ciekawe. może tam skrobnę, bo w Obj-C nadal w sumie raczkuję ;) ale czasu nie mam na to wszystko aktualnie ;]




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych