@interface ProgressiveOperation : NSOperation{
ProgressiveOperationStatus operationStatus;
}
//some methods, etc
@end
it's just a handy little asynchronous operation to plug into the NSOperationQueue. It expects a delegate of a certain protocol to notify the UI that stuff is happening. It seems to work nice. Here's an example of a class that extends it for some trackable asynchronous functionality.
@interface WebRequestWrapper : ProgressiveOperation{
}
@property(readonly, getter=responseBufferType) WebRequestResponseBufferType responseBufferType;
//some methods, etc
@end
There's a lot more to this class, but it runs an NSURLConnection, updates progress as data comes in, and other nice things. One piece of functionality surrounds that mysterious property. WebRequestResponseBufferType is an enum that defines either file or memory. You see, i have a need to stream the response data directly to a file when my app receives lengthy ammounts of data from the server. This request wrapper can either save the response data to a memory buffer (as recommended by apple) or directly to a file. If you are curious, in the connection: didReceiveData: method, i write the data directly to an NSFileHandle instance. It's very fast and minimizes memory impact. I'm not really sure why Apple doesn't want you to do this as IOS devices are generally memory starved and I find this useful. That's another topic though.
I further extend this class to provide wrappers for specific urls that my app requests. some of these are small requests that go to memory, some are large data updates that go to a file. Because the getter is not synthesized, an subclass can just implement the getter to return the value that makes sense for it. I felt that the memory buffer model should be the default, so my implementation for WebRequestWrapper looked something like this.
@implementation WebRequestWrapper
@synthesize responseBufferType;
-(WebRequestResponseBufferType) responseBufferType{
return WEbRequestResponseBufferTypeMemory;
}
//methods and stuff
@end
Now, if you are an obj-c programmer, I'm sure you see what I did wrong. There's no need to synthesize a readonly property with a user supplied getter. Let me assure you, there is a fair bit more code in this class that masks this. Also my use of the user supplied getter was added after the class had worked with a member variable that was sometimes fiddled with by subclasses. Maybe it's the .NET speaking, but I rather like the pattern of defining an abstract property to provide these kind of configuration values to superclasses.
What happened when I tried to compile this code is where things got really weird. I expect it was generating 2 identical responseBufferType signatures in the class, but the compilation error I received said that operationStatus didn't exist. WTF? it didn't tell me that any other member from the superclass was missing. It didn't complain about a redefinition of the method. The compiler appears to have cherry picked a member at random and said it didn't exist.
This was harder to figure out than the time i wrote
#define NumTableSections 2;
No comments:
Post a Comment