Skip to content

Instantly share code, notes, and snippets.

@infotroph
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save infotroph/448abd19357a0418e7ad to your computer and use it in GitHub Desktop.
Save infotroph/448abd19357a0418e7ad to your computer and use it in GitHub Desktop.
pointer-like variable updating between classes?
I have a parser inherited from someone else, and would rather not modify it if I don't have to.
The TL;DR on what's below: "Do I have to modify it?"
To pick the character encoding of its input, the parser is capable of either taking a
character encoding argument or of sniffing the encoding itself. Its designated initializer
method takes a pointer to an encoding:
-(instanceType)initWithStream:(NSStream)stream usedEncoding:(NSStringEncoding *)encoding;
and I understand the idea is that I check the pointee to see whether the parser updated its value when
it sniffed encoding:
NSStringEncoding _encoding=SOMEDEFAULTVALUE;
MyParser *p = [[MyParser alloc] initWithStream:stream usedEncoding:&_encoding;
[p parse]
if(_encoding != SOMEDEFAULTVALUE){
NSLog(@"Encoding changed to %lu", _encoding);
}
Trouble is, the parser passes most of its other results back through delegate messages,
so the sensible place to store the encoding would be in the MyParserDelegate object, so this becomes:
NSStringEncoding _encoding=NULL;
MyParserDelegate *pd = [[MyParserDelegate alloc] init];
MyParser *p = [[MyParser alloc] initWithStream:stream usedEncoding:&_encoding;
[p setDelegate:pd];
[p parse];
[pd setUsedEncoding:_encoding]
which is annoying because the parser posts a didFinishParsing message immediately at the end of parsing
and I want the delegate to consult usedEncoding in deciding how to handle didFinishParsing...
but with the current code I don't have a chance to update pd.usedEncoding until after didFinishParsing
has already fired.
Conceptually, I'd like to have the same effect as if the parser could directly update one
of the delegate's instance variables, e.g. I understand that
MyParserDelegate *pd = [[MyParserDelegate alloc] init];
MyParser *p = [[MyParser alloc] initWithStream:stream usedEncoding:&pd.usedEncoding];
is illegal and rightfully so, but want a similar result.
My options as I see them:
* Initialize my parser from inside my ParserDelegate
(maybe in the init method, so it's all just one call?)
* Have ParserDelegate return some kind of promise on didFinishParsing
and then wait for me to [pd setUsedEncoding] before it proceeds
* rewrite the darn parser to pass the encoding as a message instead of a pointer.
* ???
@aredridel
Copy link

Sniffing encoding = always wrong, but sometimes useful.

@aredridel
Copy link

Can you alias the encoding, or is it copied internally in the delegate?

NSStringEncoding _encoding=NULL;
MyParserDelegate *pd = [[MyParserDelegate alloc] init];
MyParser *p = [[MyParser alloc] initWithStream:stream usedEncoding:&_encoding;
[pd setUsedEncoding:&_encoding] 
[p setDelegate:pd];
[p parse];

@aredridel
Copy link

Or can you tell the delegate about the parser, so it can query it directly?

NSStringEncoding _encoding=NULL;
MyParser *p = [[MyParser alloc] initWithStream:stream usedEncoding:&_encoding;
MyParserDelegate *pd = [[MyParserDelegate alloc] initWithParser: p];
[p setDelegate:pd];
[p parse];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment