alle Zeichen (außer die Buchstaben von a-z) in NSSTRING ersetzen

Ich hatte nicht von Eigenschaften gesprochen sondern von Mutable vs. Immutable im Allgemeinen. Dass man von Außen nicht unkontrolliert Eigenschaften ändern sollte, ist ziemlich klar. Es geht also im Allgemeinen um das Vermeiden von Seiteneffekten, danke.
 
@Wegus: Ja dessen bin ich mir bewusst ;) Es ist ja nicht so, dass ich nicht weiß, wozu das da ist. Dass Allerdings das Framework in erster Linie mit Immutable Objects um sich schmeißt, finde ich schon recht aufwändig.
 
Hab ich auch zuerst gedacht aber: Nein, kann man sich nicht. Anforderung nicht gelesen ;)
Doch, habe ich.

Er will JEDEN Buchstaben, der nicht im Set ist, durch eine '0' ersetzen.
Ja, so hatte ich ihn auch verstanden und das macht der Code auch. (Wobei dort der Set bereits "umgedreht ist, also die unzulässigen Zeichen enthält.)

Dazu kann ich keinen statischen @"YOURREPLACESTRINGHERE" String nehmen, sondern muss für jede Ersetzung zumindest die Länge kennen.
Die Länge ist 1. Immer.

Code:
  NSCharacterSet* illegalSet = [NSCharacterSet characterSetWithCharactersInString:@"AA"];
   NSString* inText = @"BAAN";
   NSArray* components = [inText componentsSeparatedByCharactersInSet: illegalSet];
   NSString* outText = [components componentsJoinedByString:@"0"];
   NSLog( @"%@", outText );
Code:
2009-07-27 09:26:22.083 Card Game[15062:813] B00N
Die Schleife erschien mir da als die eingängigste Variante, auch wenn man das anders lösen kann.
Ich hätte ne andere Schleife genommen, aber Schönheit liegt im Auge des Betrachters.
 
Das "Verbot" von Mutables hat nichts mit Threads zu tun, sondern mit der Kapselung. Es wäre möglich, Eigenschaften einer Instanz zu ändern, ohn dass die Instanz dies bemerkt.
Wenn du das nicht willst, darf #bookings halt nur eine Kopie zurückgeben. Wenn du jetzt intern ein NSArray einsetzt nur, weil man das ansonsten ändern könnte, greifst du das Problem an der völlig falschen Stelle an, denn die Kapselung hattest du ja vorher mit #bookings selbst gebrochen.
 
Wenn du das nicht willst, darf #bookings halt nur eine Kopie zurückgeben.
Das zusätzlich, hilft aber nicht alleine. Siehe hierzu meinen nächsten Beitrag, den ich gerade schreiben wollte. :)

Wenn du jetzt intern ein NSArray einsetzt nur, weil man das ansonsten ändern könnte, greifst du das Problem an der völlig falschen Stelle an, denn die Kapselung hattest du ja vorher mit #bookings selbst gebrochen.
Nein, die Kapselung bedetet nicht, dass man die Eigenschaft nicht verndern darf. Sie bedeutet nur, das man die Eigenschaft nur über die dafür vorgesehenen Methoden verändern darf. Das Problem habe ich oben mit Beispielcode gezeigt.
 
In Java bin ich da mal drübergestolpert.
Habs gerade in Objective-C/Cocoa ausprobiert. Es lässt sich gar kein mutable Object als Key ablegen.

Was du hier meist, ist mutmaßlich etwas missverständlich:

Natürlich kann man prinzipiell Mutables als Klasse für den Wert hinter einem Key verwenden. Allerdings bekommt man zuweilen keinen Mutable – und sogar der Compiler merkt das nicht:
Code:
@interface MutableImmutableScheissable : NSObject {
   NSMutableString* text;
}
@property( copy ) NSMutableString* text;
@end

@implementation MutableImmutableScheissable
@synthesize text;

- (id)init
{
   self = [super init];
   if( self ) {
      NSMutableString* myText = [NSMutableString string];
      [self setValue:myText forKey:@"text"];
      myText = [self valueForKey:@"text"];
      [myText appendString:@"Amin"];
   }
   return self;
}
@end
Code:
2009-07-27 09:47:37.161 Card Game[15380:813] An uncaught exception was raised
2009-07-27 09:47:37.209 Card Game[15380:813] Attempt to mutate immutable object with appendString:
2009-07-27 09:47:37.231 Card Game[15380:813] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'
2009-07-27 09:47:37.240 Card Game[15380:813] Stack: (
    2436178091,
    2464689723,
    2436177547,
    2436177610,
    2523128314,
    12476,
    14996,
    2436237493,
    2455602154,
    2455561750,
    2455560056,
    2455559099,
    2455558905,
    2455558056
)
 
Ich hatte nicht von Eigenschaften gesprochen sondern von Mutable vs. Immutable im Allgemeinen.
Ich hatte das hier zugrunde gelegt:
Dann verlierst du aber eben die "Unverletzlichkeit" der Objekte!

Dass man von Außen nicht unkontrolliert Eigenschaften ändern sollte, ist ziemlich klar. Es geht also im Allgemeinen um das Vermeiden von Seiteneffekten, danke.
Ja, unabhängig von Threads. Nicht dass hier noch jemand auf den Gedanken kommt, es sei ungefährlich, wenn man keine Threads hat.
 
Tatsächlich. Ich dachte, da wäre componentsSeperatedByString klüger (dümmer)?
Ich tendiere zu dümmer. Ich denke, dass die Hauptanwendung doch das Parsen von Strings ist, die Parameter enthalten. Und da ist es ja häufig so, dass Parameter leer blieben dürfen:
Code:
5,6,,8,2,,,1,2
Stell dir vor, dass du dort
Code:
(5,6,8,2,1,2)
bekämst.
 
Was du hier meist, ist mutmaßlich etwas missverständlich:

Natürlich kann man prinzipiell Mutables als Klasse für den Wert hinter einem Key verwenden.

Dein Error kommt aber eher davon, dass die property "text" von "MutableImmutableScheissable" (interessanter Name übrigens) einen copy-getter hat. Dadurch wird eine immutable copy erstellt, die du natürlich nicht wie einen NSMutableString behandeln kannst.

Was ich meinte, war ein mutable Object als Key, und das lässt der Compiler nicht zu. Nicht mal, wenn es in einem eigenen Objekt gekapselt ist.
Der einzige Workaround imho wäre den Hash-Wert manuell zu berechnen. Siehe dort.
 
Dein Error kommt aber eher davon, dass die property "text" von "MutableImmutableScheissable" (interessanter Name übrigens) einen copy-getter hat. Dadurch wird eine immutable copy erstellt, die du natürlich nicht wie einen NSMutableString behandeln kannst.
Das weiß ich. Übrigens: Nicht eher, sondern ganz bestimmt.

Was ich meinte, war ein mutable Object als Key, und das lässt der Compiler nicht zu. Nicht mal, wenn es in einem eigenen Objekt gekapselt ist.
Das hätte ich gerne genauer. Wenn du mir ein Stück Queltext zeigt, bei dem der Compiler eine Instanz von NSString nimmt und eine von NSMutableString nicht nimmt, wäre das ein Fall für einen Bugreport. Das wäre nämlich ein Bug des Compilers.

Der einzige Workaround imho wäre den Hash-Wert manuell zu berechnen. Siehe dort.
Wenn du das mal aufmerksam liest, bemerkst du, dass es bei Mutable gar keine Implementierung von -hash gibt, außer derjenigen, die für sämtliche Instanzen denselben Wert liefert, unabhängig davon, was in den Instanzen gespeichert ist. Das kann man formal noch Hash nennen, er erfüllt aber nicht seine Funktion.

Abgesehen davon ist es bei einem Key von einem NSDictionary so, dass auf diesen ein -copy ausgeführt wird, so dass dieser stets unveränderlich ist.

Zeig mir bitte mal Code, wo der Compiler irgendwas nicht akzeptiert. Ich habe schon lange keinen Bugreport mehr an Apple geschickt.
 
Das hätte ich gerne genauer. Wenn du mir ein Stück Queltext zeigt, bei dem der Compiler eine Instanz von NSString nimmt und eine von NSMutableString nicht nimmt, wäre das ein Fall für einen Bugreport. Das wäre nämlich ein Bug des Compilers.

Da möchte ich mich jetzt entschuldigen, ich hatte die Fehlermeldung falsch gedeutet. Sie bezog sich nicht auf das einzufügende Objekt, sondern auf das Dictionary.
Meine Güte, so ein Anfängerfehler :shame:
Code:
NSMutableDictionary* dict = [NSDictionary dictionary];
Dabei war ich mir so sicher, etwas gefunden zu haben...
Naja, Gier macht blind.

Wenn du das mal aufmerksam liest, bemerkst du, dass es bei Mutable gar keine Implementierung von -hash gibt, außer derjenigen, die für sämtliche Instanzen denselben Wert liefert, unabhängig davon, was in den Instanzen gespeichert ist. Das kann man formal noch Hash nennen, er erfüllt aber nicht seine Funktion.

Abgesehen davon ist es bei einem Key von einem NSDictionary so, dass auf diesen ein -copy ausgeführt wird, so dass dieser stets unveränderlich ist.

Irgendwie versteh ich das anders. Wo hast du das mit der Implementierung von -hash gelesen?

Es ist nicht meine Absicht, dich hier schlecht hinzustellen oder auf meine Meinung zu beharren. Ich versuche nur tiefere Einsichten in Cocoa/Objective-C zu erhalten. Und wenn ich etwas falsch verstanden habe, dann hilf mir bitte das richtig zu verstehen ;)
 
Da möchte ich mich jetzt entschuldigen, ich hatte die Fehlermeldung falsch gedeutet. Sie bezog sich nicht auf das einzufügende Objekt, sondern auf das Dictionary.
Meine Güte, so ein Anfängerfehler :shame:
Code:
NSMutableDictionary* dict = [NSDictionary dictionary];
Dabei war ich mir so sicher, etwas gefunden zu haben...
Naja, Gier macht blind.
Hehehehehehe, so etwas passiert. Uns allen.

Irgendwie versteh ich das anders. Wo hast du das mit der Implementierung von -hash gelesen?

Es ist nicht meine Absicht, dich hier schlecht hinzustellen oder auf meine Meinung zu beharren. Ich versuche nur tiefere Einsichten in Cocoa/Objective-C zu erhalten. Und wenn ich etwas falsch verstanden habe, dann hilf mir bitte das richtig zu verstehen ;)
Das ergibt sch unmittelbar aus der von dir verlinkten Doku und zwar aus der Kombination von zwei Anforderungen:

Anforderung 1: Wenn zwei Instanzen gleich sind, dann müssen diese den selben Hashwert haben:
If two objects are equal (as determined by the isEqual: method), they must have the same hash value. This last point is particularly important if you define hash in a subclass and intend to put instances of that subclass into a collection.
Anforderung 2: Der Hashwert darf sich nicht ändern, wenn sich die INstanz in einer Collection befindet:
If a mutable object is added to a collection that uses hash values to determine the object’s position in the collection, the value returned by the hash method of the object must not change while the object is in the collection.
Bei einem Mutable verhält es sich ja so, dass er sich nachträglich verändern kann. Deshalb kann er auch nachträglich gleich einer anderen Instanz derselben Klasse sein. Dann muss er aber (nachträglich oder von Anfang an) denselben Hashwert haben.

Das kann ich nur sicherstellen, wenn ich allen Instanzen denselben Hashwert geben. Denn sobald ich einer Instanz einen anderen gebe, könnte sich später durch Änderungen diese Instanz als gleich herausstellen. Klar? Ach, langer Rede kurzer Sinn:
Code:
NSMutableString* amin = [NSmutableString stringWithString:@"Amin"];
// Diese Instanz bekommt einen Hash x

NSMutableString* aminNegmAwad = [NSMutableString stringWithString:@"Amin Negm-Awad"];
// Diese Instanz bekommt einen Hash y

// Beide rein inne Colleciton:
[NSArray arrayWithObjects:amin, aminNegmAwad, nil];
// Nehmen wir, dass Arrays Hashing benutzen. 

// Bisher kein Problem, aber jetzt:
[amin appendString:@" Negm-Awad"];
// Beide Mutables sind jetzt inhaltsgleich (Das Gleiche aber nicht dasselbe). 

// Ich darf x nicht ändern, weil bereits in der Collection
// x muss aber auch gleich y sein, da Inhalt gleich
// Das kann ich nur gewährleisten, wenn von Anfang an x = y
// Daraus folgt: x, y = konstant
Die Leute glauben ja nie, wie vorteilhaft Immutables sind. Ich hatte gerade erst andernortes eine Diskussion darüber, die ich dann irgendwann aufgab. Glaube es mir: Immutables sind sinnvoll, sehr sinnvoll. Und mansollte sie aus zahlreichen Gründen verwenden, wenn es irgendwie geht.
 
Das ist genau mein Standpunkt. Immutables sind wichtig und sollen, wann immer es angebracht ist, verwendet werden.

Zum Hashwert von Mutables: Ok, dann sind wir fast einer Meinung. Ich hatte das anders verstanden.
Wenn du das mal aufmerksam liest, bemerkst du, dass es bei Mutable gar keine Implementierung von -hash gibt, außer derjenigen, die für sämtliche Instanzen denselben Wert liefert, unabhängig davon, was in den Instanzen gespeichert ist. Das kann man formal noch Hash nennen, er erfüllt aber nicht seine Funktion.
Für mich liest sich das so: Mutables haben keinen Hashwert, zumindest nicht im klassischen Sinne. Quasi ein Hashwert pro Klasse.
Auch deine Aussage im zweiten Post verstehe ich nicht ganz:
Das kann ich nur sicherstellen, wenn ich allen Instanzen denselben Hashwert geben.
Eigentlich müsste ich allen Instanzen einen garantiert unterschiedlichen Hashwert geben, oder?

Langer Rede kurzer Sinn: Wirf nie mutables in eine Collection ;)
Ich glaube, da sind wir uns einig.
 
Es war genau so gemeint, wie du es verstanden hast: Alle Instanzen einer Klasse, die sich verändern können, müssen ein- und denselben Hashwert haben.

Ich fand eigentlich, dass ich das recht ausführlich erklärt habe. Aber vielleicht zeigst du mir einfachmal eine Implementierung von -hash, die unterschiedliche Werte erzeugt. Ich zeige dir dann Samplecode, indem du gegen die Anforderungen verstößt.
 
Es war genau so gemeint, wie du es verstanden hast: Alle Instanzen einer Klasse, die sich verändern können, müssen ein- und denselben Hashwert haben.

Das müssen versteh ich nicht ganz. Nur weil es passieren kann?
z.B.:
Code:
NSMutableString* string1 = [NSMutableString stringWithString:@"test"];
NSMutableString* string2 = [NSMutableString stringWithString:@"test2"];
string1 und string2 haben unterschiedliche Hashwerte. Es sind jedoch beide Instanzen einer Klasse die sich verändern können.
Nach
Code:
[string2 replaceCharactersInRange:NSMakeRange([string2 length]-1, 1) withString:@""];
schaut es schon anders aus.
 
Das müssen versteh ich nicht ganz. Nur weil es passieren kann?
z.B.:
Code:
NSMutableString* string1 = [NSMutableString stringWithString:@"test"];
NSMutableString* string2 = [NSMutableString stringWithString:@"test2"];
string1 und string2 haben unterschiedliche Hashwerte. Es sind jedoch beide Instanzen einer Klasse die sich verändern können.
Und wenn du dem ersten String eine 2 anhängst, werden Sie gelich und dann müssen sie denselben Hashwert haben.
Nach
Code:
[string2 replaceCharactersInRange:NSMakeRange([string2 length]-1, 1) withString:@""];
schaut es schon anders aus.
Und wenn du die Strings bereits in einer Collection hast, dann darfst du jetzt den Hashwert nicht mehr verändern.

Deine Implementierung verstößt also gegen die Regeln.
 
Ok, jetzt hab ichs. Du sprichst von Instanzen einer Klasse und meinst unterschiedliche Instanzen mit gleichem Inhalt, während ich von unterschiedlichen Instanzen gesprochen habe. Natürlich können diese sich ändern und gleich werden. Dann haben sie den selben Hashwert.
 
Ok, jetzt hab ichs. Du sprichst von Instanzen einer Klasse und meinst unterschiedliche Instanzen mit gleichem Inhalt, während ich von unterschiedlichen Instanzen gesprochen habe. Natürlich können diese sich ändern und gleich werden. Dann haben sie den selben Hashwert.

Den du aber nicht anpassen darfst, weil sich die Instanzen möglicherweise bereits in einer Collection befinden, die mit Hashes arbeiten … (Anforderung 2)
 
Zurück
Oben Unten