- Mattias Hedman
- Medlem ●
- Sundsvall
Du jämför pekarna inte "innehållet" i pekarna som thopabompa skriver.
Två pekare är likadana alltså TRUE.
Det är inte förren du jämför "innehållet" i pekarna du får det resultat du vill ha, alltså FALSE.
Det är när man kommer till liknande rader jag inser att det är dags att lägga boken åt sidan och ta sig an de där 10 timmars sömn författaren anser att man behöver varje natt. (Hoppas barnen sover till 9 och att jobbet ursäktar mig för att jag kommer ett par tre timmar sent.)
"The first expression compares the two pointers. The second expression compares the characters in the strings. Note, however, that if x and y are instances of a class that has not overridden NSObject's isEqual: method, the two expressions are equivalent."
Läser igenom kapitel 1, 2 och 3 för andra gången och nu börjar det definitivt sätta sig lite bättre. Dock finns det fortfarande vissa saker som jag inte helt förstår.
1. Vad är egentligen id för typ av objekt? Som jag har fattat det är det ett generellt objekt. Innebär?
2. Vad är NSNumber för typ av objekt? En kombination av int, float osv?
3. Vad är det som händer i denna kodsnutten, speciellt inom parenteserna efter for?
for (LotteryEntry *entryToPrint in array) {
// Display its contents
NSLog(@"%@", entryToPrint);
}
Tydligen anropar den en metod som heter description i LotteryEntry.m. Är det en "standardmetod" (i brist på bättre ordval) den alltid anropar när man försöker skriva ut klassen?
4. "A few of the initializers in Cocoa will return nil if initialization was impossible". Vad för typ av klasser är det som inte skulle klara av detta, och borde jag alltid kolla ifall [super init] returnerar nil i en init-metod?
Finns väl ett par andra frågetecken jag inte kommer på nu, men annars känns det som att det sitter rätt bra. I alla fall för att förstå koden. Debuggern verkar lite halvtrist, men säkert jätteanvändbar den dagen man gjort något katastroffel
Läser igenom kapitel 1, 2 och 3 för andra gången och nu börjar det definitivt sätta sig lite bättre. Dock finns det fortfarande vissa saker som jag inte helt förstår.
1. Vad är egentligen id för typ av objekt? Som jag har fattat det är det ett generellt objekt. Innebär?
2. Vad är NSNumber för typ av objekt? En kombination av int, float osv?
3. Vad är det som händer i denna kodsnutten, speciellt inom parenteserna efter for?
for (LotteryEntry *entryToPrint in array) {
// Display its contents
NSLog(@"%@", entryToPrint);
}
Tydligen anropar den en metod som heter description i LotteryEntry.m. Är det en "standardmetod" (i brist på bättre ordval) den alltid anropar när man försöker skriva ut klassen?
4. "A few of the initializers in Cocoa will return nil if initialization was impossible". Vad för typ av klasser är det som inte skulle klara av detta, och borde jag alltid kolla ifall [super init] returnerar nil i en init-metod?
Finns väl ett par andra frågetecken jag inte kommer på nu, men annars känns det som att det sitter rätt bra. I alla fall för att förstå koden. Debuggern verkar lite halvtrist, men säkert jätteanvändbar den dagen man gjort något katastroffel
1) Du använder id när du inte vill ange vad för typ av objekt du pekar på. Om du har olika slags objekt i en array t. ex. kan samma metod hantera dem. Fördelen med att inte använda id om man kan, är att kompilatorn fångar en del fel som den inte kan se om ett objekt inte är typat.
2) Ett objekt av klassen NSnumber kan hålla en int, float, double etc. Viktigt är att det till skillnad från en int t. ex. är ett objekt, inte en C-typ.
3) Alla klasser är underklasser till NSObject. NSObject har en metod som heter (NSString*)description, vilken således alla klasser ärver. Vissa klasser har en egen implementation av metoden, de override metoden och returnerar en egenihopknåpad sträng. Du kan själv skriva en klass med egen implementation av metoden.
4) Det verkar vara god praxis att göra så. Jag har dock aldrig varit med om några problem med att inte kolla. Någon kunnigare än jag kanske kan förklara när, och varför det behövs. (Jag kan förstå att det är bra att man får reda på direkt om något går fel, istf en luddig krasch någon gång senare).
Vänligen, Ylan
Ylan, jag läser ditt inlägg med intresse. Rent tekniskt har du rätt i det mesta, men jag håller inte med om dina slutsatser. Just möjligheten att "gå ner ett lager" och "optimera metoder genom att skriva om dem i ett lågnivåspråk" åberopas ofta som viktiga instrument men det köper jag helt enkelt inte. Jag har inga siffror, men jag misstänker att det endast är i undantagsfall man nånsin behöver göra detta, och då enbart för t ex extremt beräkningsintensiva program. (Nu är min professionella systemutvecklarkarriär iofs bara inne på sitt tredje år, men jag tror mig ha ganska god koll på branchen.)
Med det sagt ser jag ändå inte hur detta skulle vara en fördel med Obj-Cs (alla äldre C-språks) antika minneshantering. I de allra flesta språk, så även t ex Java och VB/C#.NET kan man, vid behov, ändå använda pekare och allokera minne manuellt om behovet skulle uppstå. Vilket det mycket sällan gör. Det är alltså inte främst GC jag är för, utan möjligheten att helt abstrahera bort det faktum att datorn har ett fysiskt internminne (precis som man redan gjort med nätverksströmmar, filpekare, filallokeringstabeller mm).
Ylan, jag läser ditt inlägg med intresse. Rent tekniskt har du rätt i det mesta, men jag håller inte med om dina slutsatser. Just möjligheten att "gå ner ett lager" och "optimera metoder genom att skriva om dem i ett lågnivåspråk" åberopas ofta som viktiga instrument men det köper jag helt enkelt inte. Jag har inga siffror, men jag misstänker att det endast är i undantagsfall man nånsin behöver göra detta, och då enbart för t ex extremt beräkningsintensiva program. (Nu är min professionella systemutvecklarkarriär iofs bara inne på sitt tredje år, men jag tror mig ha ganska god koll på branchen.)
Med det sagt ser jag ändå inte hur detta skulle vara en fördel med Obj-Cs (alla äldre C-språks) antika minneshantering. I de allra flesta språk, så även t ex Java och VB/C#.NET kan man, vid behov, ändå använda pekare och allokera minne manuellt om behovet skulle uppstå. Vilket det mycket sällan gör. Det är alltså inte främst GC jag är för, utan möjligheten att helt abstrahera bort det faktum att datorn har ett fysiskt internminne (precis som man redan gjort med nätverksströmmar, filpekare, filallokeringstabeller mm).
Jag förstår dina synpukter, och ser att man kan se Obj-C, som jag skrev, som ett kraftfullt språk med tillgång till flera abstraktionsnivåer, men likaväl som en omodern halvmessyr.
Samtidigt finns det väl inte många stora desktopapps till Windows som är skrivna i Java eller VB/C#.NET, utan snarare i C eller C++ som väl knappast kan sägas vara på högre nivå än Obj-C/Cocoa. Vet inte huruvida det beror på de stora appsens ålder eller deras prestandakrav.
Apple försöker ju också abstrahera språket med GC och ramverken med Core Data och andra nya Cocoa API:er. Och Apple äter ju verkligen sin egen hundmat.
Måhända är det så att Apple inte har kapaciteten att utveckla på två (ganska åtskilda) nivåer, utan får nöja sig med sin "halvmessyr", med bryggor åt språk som Python och Ruby.
Jag är dock övertygad om att du får rätt på sikt. Abstraktion vinner över prestanda över tid, med snabbare och snabbare burkar som drivmedel.
Vänligen, Ylan
Ylan: Tack så mycket, det hjälpte verkligen!
Ursäkta om jag är tjatig nu, menhar fastnat på en uppgift. Jag ska räkna antalet karaktärer i ett textfält för att sedan skriva ut resultatet i en label.
Kod:
#import "AppController.h" @implementation AppController - (id) init { [super init]; NSLog(@init); return self; } - (void) awakeFromNib { [labelCount setObjectValue:@""]; } - (IBAction) count:(id)sender { NSString *string = [textField stringValue]; int stringLength = [string length]; NSLog(@"%@", string); if (stringLength != 0) { NSString *labelString = (@"The string has %d characters", stringLength); [labelCount setStringValue:labelString]; } }
Har lyckats lösa alla felmeddelanden förutom en, "Initialization makes pointer from integer without a cast" som sker vid raden NSString *labelString = (@"The string has %d characters", stringLength);. Är säker på att det är något enkelt skitfel, men ser det verkligen inte.
Kanin, du måste skapa objektet på vilket pekaren labelString pekar, det gör du inte i
NSString *labelString = (@"The string has %d characters", stringLength);
Du säger att pekaren skall bli ett objekt, vilket den inte kan.
Använd en convenience method som denna:
NSString *labelString =[NSString stringWithFormat: @"The string has %d characters", stringLength];
Eftersom du inte är intresserad av att behålla objektet (strängen) efter att ha loggat det, kan du använda en class method som denna "+ (NSString *)stringWithFormat: (NSString *)" som skapar, och returnerar en pekare till, ett autoreleased object. Pekaren lagrar du sedan i din variabel labelString.
Man kan säga att detta problem är en del av precis det memark tar upp i sin kritik av Obj-C: Det kräver att man verkligen förstår vad en pekare är, dvs. inget mer än en minnesadress.
Vänligen, Ylan
Ojdå, vi var många om budet, och om tråden är en del off topic, och innehåller en del skilda åsikter, tycker jag den är ganska trevlig, och jag hoppas att trådskaparen tycker det samma!
Annars, får du påpeka detta Mattias, så flyttar vi på oss!
Vänligen, Ylan
Tråden är lärorik och den håller en bra nivå.
Kanin, tycker dina frågor är bra. Vi lär av varandra!
Kanin, tycker dina frågor är bra. Vi lär av varandra!
Kul att höra!
Passar väl på med en till fråga...
För att lära sig Helper Objects (Hjälpobjekt?) ska man bygga ett program som använder sig av NSSpeechSynthesizer för att få datorn att läsa upp en sträng man skrivit in. När man ska göra en lista, NSTableColumn, över alla tillgängliga röster det finns att tillgå använder boken sig av NSDictionary för att klippa bort allt förutom namnet i com.apple.speech.synthesis.voice.Fred, dvs Fred, med koden:
NSString *v = [voiceList objectAtIndex:row];
NSDictionary *dict = [NSSpeechSynthesizer attributesForVoice:v];
return [dict objectForKey:NSVoiceName];
Dock förklarar inte boken hur NSDictionary fungerar. Någon som är vänlig och går igenom vad som händer i koden ovan för mig?
EDIT: Lite annat jag kom att tänka på
Man kan säga att detta problem är en del av precis det memark tar upp i sin kritik av Obj-C: Det kräver att man verkligen förstår vad en pekare är, dvs. inget mer än en minnesadress.
Har jag rätt när jag säger att jag tänker mig att pekare fungerar på samma sätt som genvägar till filer och mappar i Finder? Dvs att den hänvisar till en plats, men man kan aldrig ändra själva genvägen mer än att få den att hänvisa till en annan plats. Något utöver det?
2) Ett objekt av klassen NSnumber kan hålla en int, float, double etc. Viktigt är att det till skillnad från en int t. ex. är ett objekt, inte en C-typ.
Tror inte jag riktigt har förstått skillnaden mellan C-typ och objekt, mer än att man aldrig hanterar objekt direkt utan via pekare. Varför gör man det egentligen?
I slutet av boken finns en innehållsförteckning. På sidan 440 står det att NSDictionary finns beskrivet på sidorna 184-185 och sidan 189. Där kan man alltså läsa mer om NSDictionary. Om du har den tredje upplagan av boken kan du göra på liknande sätt
Välj "Documentation" i XCodes Help-meny. Skriv in "NSDictionary" i sökrutan uppe till höger och du hittar precis hur mycket som helst om NSDictionary.
Det går mycket snabbare att söka efter informationen själv än att fråga på detta forum. Om det är rena föreståelsefrågor hjälper jag och andra säkert till, men frågor av typen "Jag orkar inte kolla i boken eller hjälpen så jag frågar här istället" kommer snart göra att ingen vill/orkar svara. Dessutom tar det ofantligt mycket längre tid för dig!
I slutet av boken finns en innehållsförteckning. På sidan 440 står det att NSDictionary finns beskrivet på sidorna 184-185 och sidan 189. Där kan man alltså läsa mer om NSDictionary. Om du har den tredje upplagan av boken kan du göra på liknande sätt
Välj "Documentation" i XCodes Help-meny. Skriv in "NSDictionary" i sökrutan uppe till höger och du hittar precis hur mycket som helst om NSDictionary.
Det går mycket snabbare att söka efter informationen själv än att fråga på detta forum. Om det är rena föreståelsefrågor hjälper jag och andra säkert till, men frågor av typen "Jag orkar inte kolla i boken eller hjälpen så jag frågar här istället" kommer snart göra att ingen vill/orkar svara. Dessutom tar det ofantligt mycket längre tid för dig!
Att kolla i indexet i boken hade jag inte ens tänkt tanken på att göra, då jag tog för givet att han gick igenom alla delar av koden, och nämnde tydligt att de han inte går igenom får man reda på senare, för att inte lämna några frågetecken efter sig. Tack för tipset!
Dokumentationen har jag givetvis redan kollat i, men "The NSDictionary class declares the programmatic interface to objects that manage immutable associations of keys and values." gör mig tyvärr inte mycket klokare, då mina programmeringsterminologikunskaper inte är på topp. Dessutom hjälper det lite extra ibland att få saker förklarade för sig på ren svenska.
Men visst, utlämnar rena kunskapsfrågor (var går gränsen egentligen?) om det gör din dag lite gladare.
Men visst, utlämnar rena kunskapsfrågor (var går gränsen egentligen?) om det gör din dag lite gladare.
Fast egentligen var det ju mest får DIN skull om du läser motiveringen i mitt inlägg!
Om man inte fattar vad det står i dokumentationen finns det ju Internet också. Wikipedia har en del grundläggande beskrivningar. Annars kan jag rekommendera CocoaDev: CocoaDev. Där finns det många exempel och svar på andra personers frågor.
if (stringLength != 0) { NSString *labelString = (@"The string has %d characters", stringLength); [labelCount setStringValue:labelString]; }
bör vara:
if (stringLength != 0) { labelString = (@"The string has %d characters", stringLength); [labelCount setStringValue:labelString]; }
då du redan, lite längre upp i koden, deklarerat labelString som en pekare mot ett objekt av typen NSString.
Hoppas det hjälper
Ojoj, tre svar på fem minuter. Ni är för gulliga!
mrnoname: Inte vad jag kan se. Säker på det?
memark, Ylan: Ah, det är självklart så man gör! Jag testade stringWithFormat, men använde mig av parentes runt uttrycket så blev fel trots allt. Tack ännu en gång!
Och vill även jag be om ursäkt om jag överutnyttjat trådskaparens tråd.
Man kan se ett dictionary som just en... ordbok. Det innehåller kombinationer av nycklar av värden. Man kan fråga "vilket värde finns för nyckeln x?" eller "vilken nyckel finns för värdet y?". Det låter mer komplicerat än det är, så analogin med en vanlig ordbok är inte så dum.
Det som händer här är att NSSpeechSynthesizer-objektets metod returnerar ett dictionary med en massa information. Det är alltså inte nåt som kodexemplet egentligen skapar.