13 berichten aan het bekijken - 1 tot 13 (van in totaal 13)
  • Q:

    Bijdrager
    vikking

    Cocoa: NSString doet vervelend

    Ik probeer te controleren of een NSString gelijk is aan “00” en of het een integer is. De code die ik gebruik is:
    [code:1:0e8553ba12] for(i=0; i<array_count; i++){
    if(!(test_value = [[localArray objectAtIndex:i] intValue]) && [localArray objectAtIndex:i] != @"00"){
    NSLog(@"Failed at integercheck, %@ at %i", [localArray objectAtIndex:i], i);
    return FALSE;
    }
    }[/code:1:0e8553ba12]
    Vreemd, want deze code werkt wel:
    [code:1:0e8553ba12] NSString * test = @"00";
    int test_value;
    if(test_value = [test intValue] || test == @"00"){
    NSLog(@"integer");
    }else{
    NSLog(@"geen integer");
    }[/code:1:0e8553ba12]
    Alvast bedankt:)


    Bijdrager
    koen

    In de code die werkt gebruik je ||, in de code die niet werkt gebruik je &&.

    Om beter te debuggen kun je ook het volgende proberen:

    [code:1:5a62dc695d]
    NSString *testString;
    int testValue;

    for(i=0; i<array_count; i++)
    {
    testvalue = [[localArray objectAtIndex:i] intValue];
    testString = (NSString *) [localArray objectAtIndex:i];

    if( !testvalue && (testString != @"00"))
    {
    NSLog(@"Failed at integercheck, %@ at %i", [localArray objectAtIndex:i], i);
    return FALSE;
    }
    }
    [/code:1:5a62dc695d]


    Bijdrager
    DeMaccer

    je doet dit:
    [localArray objectAtIndex:i] != @”00″
    maar het object van de array op indez i moet je eerst definieren als nsstring.

    Dus dit zal wel lukken:

    [ [localArray objectAtIndex:i] stringValue ] != @”00″


    Bijdrager
    vikking
    ”DeMaccer”

    je doet dit:
    [localArray objectAtIndex:i] != @”00″
    maar het object van de array op indez i moet je eerst definieren als nsstring.

    Dus dit zal wel lukken:

    [ [localArray objectAtIndex:i] stringValue ] != @”00″

    *** -[NSCFString stringValue]: selector not recognized [self = 0x394540]

    Werkt dus niet

    @koen: ik gebruik in 2de stuk || omdat eerst komt als als het true is (dus een integer) en bij de echte code gebruik ik && omdat het daar andersom is


    Bijdrager
    koen
    ”vikking”

    [

    *** -[NSCFString stringValue]: selector not recognized [self = 0x394540]

    Werkt dus niet[/quote]
    Waarschijnlijk omdat het object al een NSString is, en die kent de functie stringValue niet. Probeer eens de isEqualToString: functie om de twee strings te vergelijken.

    Wat gebeurt er als je stap voor stap door de code gaat, wat zijn de waarden voor testValue en testString (zie mijn code voorbeeld)?


    Bijdrager
    Reflex

    Daarnaast dien je in Objective-C objecten nooit tevergelijken met de operators == of !=. Dit omdat deze slechts het adres van het object zal vergelijken en niet de waarde…

    Het merendeel van de Foundation classes heeft wel een isEqual of compare implementatie…

    [edit]
    Wat meer uitwerking
    NSString * aString = [NSString stringWithString:@”koe”]; // omslachtig, maar voor de duidelijkheid

    if( aString == @”koe” ) { // vergelijkt adressen, niet content
    NSLog(@”aString == koe”);
    }

    if( [aString isEqualToString:@”koe”] ) {
    NSLog(@”aString isEqualToString”);
    }

    if( [aString compare:@”koe”] == NSOrderedSame ) {
    NSLog(@”aString compare”);
    }

    isEqualToString is eigenlijk gewoon geimplementeerd als
    – (BOOL)isEqualToString:(NSString *)other {
    return [self compare:other] == NSOrderedSame;
    }

    Je zult zien dat de onderste twee wel werken, en de eerste methode niet.

    de reguliere hash methode van NSObject (of geimplementeerd door subclassen) wordt bij isEqual gebruikt. In het geval van NSString zal isEqual ook werken, maar niet altijd een 100% betrouwbare uitkomst geven daar deze gebaseerd is op de hash methode ( -(BOOL)isEqual:(NSObject *)other { return [other hash] == [self hash]; } ) Daar NSString de hash methode implementeert werkt de isEqual methode dus wel, maar niet 100% betrouwbaar, daar hashes niet 100% uniek zijn…

    Bij hashes (in de implementatie van NSString) doet de volgorde van de tekens er niet toe
    example:
    woord: koe
    hash: 1054352243
    woord: eok
    hash: 1054352243


    Bijdrager
    Reflex

    Nog verder uitgewerkt zou je kunnen stellen (for the sake of exercise) dat

    myString = [NSString stringWithCString:”koe” encoding:NULL];

    if( myString == @”koe” )
    door de preprocessor vertaald wordt (@”” is een macro ) naar het volgende
    if( myString == [NSString stringWithCString:”koe” encoding:NULL] )

    De macro @”koe” returned dus een geheel nieuw object. Door te zeggen dat myString == new object vergelijk je de adressen van de twee objecten, en zul je dus nooit op het gewenste resultaat uitkomen. myString en ook de return value van @”koe” zijn niets meer dan pointers naar een object. In het geval van koe een constant gealloceerd object, maar nogsteeds een object…


    Bijdrager
    vikking

    @reflex en Koen: Bedankt voor de uitleg :D, nu werkt het (isEqualToString)
    Nu nogiets anders:
    [code:1:796b9f37c0]NSArray * keys = [NSArray arrayWithObjects:@"h", @"m", @"s"];[/code:1:796b9f37c0]
    zorgt ervoor dat het programma hangt… Zie ik weer iets over het hoofd?


    Bijdrager
    Reflex

    Uit de documentatie (link)

    The argument list is a comma-separated list of objects ending with nil.

    het dient dus te zijn:
    [code:1:49d1014a26]
    NSArray * myArray = [NSArray arrayWithObjects:@"a", @"b", @"c", nil];
    [/code:1:49d1014a26]


    Bijdrager
    vikking

    Whoops, daar heb ik overgelezen, bedankt!


    Bijdrager
    vikking

    Dan nogiets, in PHP kan je zeer gemakkelijk strings aaneenzetten:
    [code:1:8c6b1d4350]$string1 = "Hello";
    $string2 = " World";
    echo $string1 . $string2;[/code:1:8c6b1d4350]
    Bestaat er iets in die aard voor Cocoa? Het enige dat ik gevonden heb is stringByAppendingString:, maar die is nogal omslachtig als ik iets wil doen als:
    [code:1:8c6b1d4350][d1s setStringValue:[[[[diffhours stringByAppendingString:@":"] stringByAppendingString:diffminutes] stringByAppendingString:@":"] stringByAppendingString:diffseconds]];[/code:1:8c6b1d4350]
    Alvast bedankt.


    Bijdrager
    Reflex

    Ik stel toch voor dat je de documentatie gaat lezen van NSString

    NSString myString = [NSString stringWithFormat:@”%d:%d:%d”, diffhours,diffminutes,diffseconds];

    Daarnaast heb je natuurlijk ook de NSDate class voor dit soort grappen..

    diffHours is beter dan diffhours als variable name, btw. Ik weet dat het feitelijk niets uitmaakt, maar het komt de leesbaarheid ten goede.


    Bijdrager
    vikking

    Jah, sry, kben men weg nog een beetje aant zoeke in de handleiding, het is gewoon zoveel :P. Toch bedankt.

13 berichten aan het bekijken - 1 tot 13 (van in totaal 13)

Je moet ingelogd zijn om een reactie op dit onderwerp te kunnen geven.