问题
I'm attempting to generate an HTML-output for a model in my app. This will effectively go through and fill in various spots inside an HTML file with the relevant values within the model. I was originally just going to take the HTML template as a formatted string, but if anything changes later on the layout or anything, this will just get really messy and tedious to match up the order of the values to the order they appear in the template.
Instead, what I'm trying to do is run a sort of Ruby-style string interpolation of the file. Anywhere I want a value from the model, I put the name of the model attribute I want like so: #{key.path}
.
Then, I'm attempting to process this with the following Regex:
@"#{([^}]+)}"
.
To process this, I'm using the following setup:
NSString *processedTemplate = [regex stringByReplacingMatchesInString:template
options:0
range:NSMakeRange(0, template.length)
withTemplate:[self valueForKeyPath:@"$1"]];
However, when I run this, I get the error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException',
reason: '[<Plan 0x78349d0> valueForUndefinedKey:]: this class is not
key value coding-compliant for the key $1.'
What I expect is that I can use the regex match and use it to grab the key-value coding compliant value in my model. However, this clearly doesn't work the way I'm using it.
On a side note, I think I'm using this right, but when I just run this to replace withTemplate:@"$1"
I get NULL. So, I tried it using:
NSString *processedTemplate = [template stringByReplacingOccurrencesOfString:@"#{([^}]+)}"
withString:@"$1"
options:NSRegularExpressionSearch
range:NSMakeRange(0, template.length)];
However, when I run this it doesn't replace with the section in ()
. So one way or another, I'm not doing something right. Anyone have any pointers/solutions?
Update
So it looks like the withString:
parameter will interpret @"$1"
as whatever the regex match data has found. Is there another way to retrieve match data so it can be passed into such methods as valueForKeyPath:
?
Update
On my side note, I don't know why, but my regex #{([^}]+)}
does not match as I expect it to. Any other regex simulator I put it up against seems to match it just fine, but it doesn't match in obj-c on iOS. Is there something I'm missing with escapes on character set #{}
?
回答1:
What kind of object is self
in your first example? Have you overridden valueForKeyPath:
?
The method -valueForKeyPath:
is defined for NSObject to return a value based on KVC key paths. The code
obj = [anotherObj valueForKeyPath: @"foo.bar.baz"];
will first send foo
to anotherObj
, then send bar
to the result, then send baz
to the result of that and return the final result.
Essentially, the runtime is complaining that you don't have a method called -$1
.
And by the way, in Objective-C parameters to methods are evaluated before the method itself, so
[self valueForKeyPath:@"$1"]
is evaluated before stringByReplacingMatchesInString:
and $1
means nothing special to valueForKeyPath:
.
来源:https://stackoverflow.com/questions/8523448/ruby-style-string-interpolation-with-ios-nsregularexpression