-
Notifications
You must be signed in to change notification settings - Fork 811
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor parts of NSURLConnection #2464
Conversation
- Implement [NSURLConnection sendAsynchronousRequest:] - Re-implement [NSURLConnection sendSynchronousRequest:] on top of it, as stated in docs - Implement a not-yet fully-working setDelegateQueue: (callbacks are not yet called on it) - Remove NSURLConnectionState, replace with a lighter-weight, more flexible inner class - Changed the NSURLConnection functional tests to no longer run on the main run loop. This no longer works, which is correct (doesn't work on reference platform either) - Instead, run on another thread's run loop, and an operation queue. - Also added tests for sendSynchronousRequest: - Change parts of NSURLProtocol, NSRunLoop to use stricter typing - Change instances of NSRunLoopMode to actually say NSRunLoopMode instead of NSString* Fixes microsoft#2298
@end | ||
|
||
// Test to verify a request can be successfully made and a valid response and data is received. | ||
static void _testRequestWithURL(NSURLConnectionTestHelper* connectionTestHelper) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered doing parameterized tests, but since TAEF only parameterizes on Wex Strings, it felt like I was trying too hard to make it fit, so I opted for this instead.
if (ret) { | ||
ret->_operationQueue = queue; | ||
ret->_completionHandler = handler; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should really be in an initializer then called by the +method
|
||
[connection cancel]; | ||
std::vector<std::pair<StrongId<NSRunLoop>, StrongId<NSString>>> _scheduledRunLoops; // NSRunLoop, NSRunLoopMode | ||
// TODO #: Cannot currently schedule on more than one runloop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#: [](start = 12, length = 2)
Task ID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i know, i knowww - i dont like filing these tasks until the PR is actually out because they often lack context without the PR,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ (NSData*)sendSynchronousRequest:(NSURLRequest*)request | ||
returningResponse:(NSURLResponse* _Nullable*)response | ||
error:(NSError* _Nullable*)error { | ||
if (request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (request) { [](start = 3, length = 15)
nit: early return :p
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree 😛
[_protocol release]; | ||
[_delegate release]; | ||
[_response release]; | ||
[_originalRequest release]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[_originalRequest release]; [](start = 1, length = 30)
good candidate for StrongId
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a property, which makes it a less good candidate for StrongId
+ (NSData*)sendSynchronousRequest:(id)request returningResponse:(NSURLResponse**)responsep error:(NSError**)errorp { | ||
NSURLConnectionState* state = [[[NSURLConnectionState alloc] init] autorelease]; | ||
NSURLConnection* connection = [[self alloc] initWithRequest:request delegate:state startImmediately:FALSE]; | ||
+ (_NSURLConnection_DataDelegate*)delegateWithQueue:(NSOperationQueue*)queue handler:(void (^)(NSURLResponse*, NSData*, NSError*))handler { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: prefer all factory functions X to go through an appropriate initializer initWithX:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sigh okkkk
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:mode]; | ||
[connection start]; | ||
- (void)connectionDidFinishLoading:(NSURLConnection*)connection { | ||
[_operationQueue addOperation:[NSBlockOperation blockOperationWithBlock:^void() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we know whether the queue is fire-and-forget or fire-and-wait?
I assumed NSNotificationCenter+OperationQueue was fire-and-forget, but it actually waits for the notification block to complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's fire-and-forget
// Actual NSURLConnection implementation | ||
@implementation NSURLConnection { | ||
@private | ||
StrongId<NSObject> _delegate; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This delegate should be protocol-qualified; StrongId<NSObject<NSURLConnectionDelegate>>
@Status Interoperable | ||
*/ | ||
+ (BOOL)canHandleRequest:(id)request { | ||
return ([NSURLProtocol _URLProtocolClassForRequest:request] != nil) ? YES : NO; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also requires a -[protocolClass canInitWithRequest:]
*error = innerError ? [[innerError retain] autorelease] : nil; | ||
} | ||
|
||
data = innerData ? [[innerData retain] autorelease] : nil; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be safer to only retain
data in here and only autorelease
it outside the block. Otherwise, this +1/-1 pair could resolve when the Operation Queue loops around again and drains its pool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point.
_storagePolicy = policy; | ||
|
||
if ([_delegate respondsToSelector:@selector(connection:willCacheResponse:)]) { | ||
[_delegate connection:self willCacheResponse:response]; | ||
[_delegate connection:self willCacheResponse:static_cast<NSCachedURLResponse*>(response)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whoa, this is scary. I realize it is what was already happening, but those two things are very much not the same thing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yuuuppp, lemme leave a TODO here to fix up later.
|
||
NSURLProtocol* protocol = _protocolForRequest(request, self); | ||
if (!protocol) { | ||
TraceError(TAG, L"[NSURLConnection start] could not create a NSURLProtocol for its NSURLRequest."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not start
anymore!
TraceError(TAG, L"[NSURLConnection start] could not create a NSURLProtocol for its NSURLRequest."); | ||
return; | ||
} | ||
_protocol = protocol; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to update _request
like setRequest was doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops
_request.attach([request mutableCopy]); | ||
_cachedResponse = cachedResponse; | ||
_client = client; | ||
_request = [request mutableCopy]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm.. why move away from StrongId?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they were properties, and one was working incorrectly and not taking a copy. seemed like a good idea to just pivot to autosynthesis
@@ -251,7 +251,7 @@ - (void)startLoading { | |||
|
|||
NSError* error = nil; | |||
try { | |||
auto httpRequestMessage = _requestMessageForNS(_request); | |||
auto httpRequestMessage = _requestMessageForNS(self.request); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these getter calls seem unnecessary; NSURLProtocol for HTTP is a leaf class and cannot be subclassed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NSURLProtocol_WinHTTP doesn't have access to the superclass member now that it's synthesized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that's the case, we should at least lift these out to locals then. Otherwise, each hit is a [[_request retain] autorelease]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(the compiler can't perform common subexpression elimination as it can't prove that self.request
is idempotent)
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response { | ||
// We get some of these for each redirect. Only capture the final one. | ||
_response = response; | ||
if (!_data.get() || [_data length] > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: just use !_data for the operator bool()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didnt know that worked, til
|
||
[connection cancel]; | ||
std::vector<std::pair<StrongId<NSRunLoop>, StrongId<NSString>>> _scheduledRunLoops; // NSRunLoop, NSRunLoopMode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use NSRunLoopMode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't, NSRunLoopMode is unfortunately typedef'd as NSString* and not NSString :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh.. AutoId should be able to remove_pointer that properly. I wanted for AutoId<SNString>
and AutoId<NSString*>
to be functionally equivalent, so it strips or adds the pointer as necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh. i didn't actually try it i just figured it wouldn't work. ;;;;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it works. i'm silly.
queue:queue | ||
completionHandler:^void(NSURLResponse* innerResponse, NSData* innerData, NSError* innerError) { | ||
if (response) { | ||
*response = innerResponse ? [[innerResponse retain] autorelease] : nil; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does autorelease work within an async block? If that block is executed within an autoreleasepool, will these be released then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pretty much; oops
[_protocol startLoading]; | ||
/** | ||
@Status Caveat | ||
@Notes TODO #: Cannot currently schedule on more than one runloop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: add issue number here
format:@"A connection cannot be scheduled with both an operation queue and a run loop."]; | ||
} | ||
|
||
if (_scheduledRunLoops.size() >= 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this just be > 1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? no, as is, it only allows something in if the vector is empty, which is what i want.
|
||
/** | ||
@Status Caveat | ||
@Notes TODO #: Callbacks do not currently occur on delegate queue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: same as above
_scheduled = YES; | ||
- (void)unscheduleFromRunLoop:(NSRunLoop*)aRunLoop forMode:(NSRunLoopMode)mode { | ||
@synchronized(self) { | ||
for (auto it = _scheduledRunLoops.begin(); it != _scheduledRunLoops.end(); ++it) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: shouldn't modify a collection while iterating over it, even if it's breaking out of it at the end. Would prefer std::find() with an erase if != end()
NSInteger count = [classes count]; | ||
|
||
while (--count >= 0) { | ||
id check = [classes objectAtIndex:count]; | ||
Class check = [classes objectAtIndex:count]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: update this to be for in loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aballway This is iterating in reverse. Cheaper than a reverseObjectEnumerator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⭕️ that they are
_request.attach([request mutableCopy]); | ||
_cachedResponse = cachedResponse; | ||
_client = client; | ||
_request = [request mutableCopy]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
won't these overretain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_foo = doesn't call the setter, so everything is +1 as it should be
+ (NSData*)sendSynchronousRequest:(NSURLRequest*)request | ||
returningResponse:(NSURLResponse* _Nullable*)response | ||
error:(NSError* _Nullable*)error { | ||
if (request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree 😛
- (instancetype)init { | ||
if (self = [super init]) { | ||
self->_condition = [[NSCondition alloc] init]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[NSCondition alloc] init]; [](start = 28, length = 26)
:)
|
||
- (instancetype)init { | ||
if (self = [super init]) { | ||
self->_thread = [[NSThread alloc] initWithTarget:self selector:@selector(spinRunLoop) object:nil]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self->_thread = [[NSThread alloc] initWithTarget:self selector:@selector(spinRunLoop) object:nil]; [](start = 8, length = 98)
+1 on the init and +1 on the retain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is an arc-enabled file
include/Foundation/NSURLConnection.h
Outdated
+ (BOOL)canHandleRequest:(NSURLRequest*)request; | ||
@property (readonly, copy) NSURLRequest* originalRequest; | ||
@property (readonly, copy) NSURLRequest* currentRequest; | ||
@property (readonly, copy) NSURLRequest* currentRequest STUB_PROPERTY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
STUB_PROPERTY [](start = 56, length = 13)
while we are here, can we implement this? this should be easy...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚶
@@ -54,27 +55,32 @@ @implementation _NSURLConnection_DataDelegate { | |||
|
|||
StrongId<NSURLResponse> _response; | |||
StrongId<NSMutableData> _data; | |||
|
|||
bool _started; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, this doesn't even seem like it gets used in the body of this data delegate... but _started gets used in NSURLConnection. Did some wires get crossed?
return NO; | ||
} | ||
|
||
return [protocolClass canInitWithRequest:request]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can keep this folded, actually. [nil canInitWithRequest:request]
returns NO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(no need for the if check that the compiler is going to emit anyway)
_scheduledRunLoops.erase(it); | ||
return; | ||
} | ||
auto it = std::find(_scheduledRunLoops.begin(), _scheduledRunLoops.end()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this appears to be finding "the run loop"? It doesn't care about its arguments. If that's the case, why not just _scheduledRunLoops.clear()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ugh this is what i get for rushing on friday...
NSURLConnection* connection = [self _createConnectionWithRequest:URLString]; | ||
[connection setDelegateQueue:_operationQueue]; | ||
// [connection setDelegateQueue:[NSOperationQueue new]]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, ty for catching
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: prefer not cluttering the URL tests with URL Download tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, I was testing something on the reference platform and apparently forgot to delete this?
[connectionTestHelper.condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]]; | ||
} | ||
ASSERT_EQ_MSG(2, [connectionTestHelper.delegateCallOrder count], "FAILED: We should have received two delegates call by now!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: delegate calls
|
||
// Make sure there was no error. | ||
ASSERT_TRUE_MSG((connectionTestHelper.error == nil), "FAILED: Connection returned error %@!", connectionTestHelper.error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: assert_eq?
|
||
// Test to verify a request can be successfully made but no data was received and a valid response error code was received. | ||
static void _testRequestWithURL_Failure(NSURLConnectionTestHelper* connectionTestHelper) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this appears unused
@synchronized(self) { | ||
auto it = std::find(_scheduledRunLoops.begin(), _scheduledRunLoops.end()); | ||
if (it != _scheduledRunLoops.end()) { | ||
_scheduledRunLoops.erase(it); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, shouldn't this call something on the runloop to unschedule ourselves?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Use this method to unschedule the connection from an undesired run loop and mode before starting the connection.
You cannot reschedule a connection after it has started."
@@ -110,18 +109,15 @@ @implementation NSURLConnection { | |||
StrongId<NSURLResponse> _response; | |||
NSURLCacheStoragePolicy _storagePolicy; | |||
StrongId<NSURLProtocol> _protocol; | |||
|
|||
bool _started; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(is this superior to property autosynthesis? it looks like there's already a property for this ivar, and the ivar will be automatically generated just like it was before this change)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
? There's no property for this ivar.
auto it = std::find(_scheduledRunLoops.begin(), _scheduledRunLoops.end()); | ||
auto it = std::find_if(_scheduledRunLoops.begin(), | ||
_scheduledRunLoops.end(), | ||
[aRunLoop](std::pair<StrongId<NSRunLoop>, StrongId<NSRunLoopMode>>& pair) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this ref be const?
auto it = std::find_if(_scheduledRunLoops.begin(), | ||
_scheduledRunLoops.end(), | ||
[aRunLoop](std::pair<StrongId<NSRunLoop>, StrongId<NSRunLoopMode>>& pair) { | ||
return aRunLoop == pair.first.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: AutoId should have an operator== for T (but I wouldn't be surprised if it didn't)
ping! |
ping! last call @msft-Jeyaram @aballway @rajsesh-msft |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops thought I approved this already 🇱🇦
@implementation NSURLConnection | ||
// Private helper function that returns a NSURLProtocol object capable of handling a NSURLRequest | ||
// Returns nil if one cannot be created | ||
static NSURLProtocol* _protocolForRequest(NSURLRequest* request, id<NSURLProtocolClient> client) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_protocolForRequest [](start = 22, length = 19)
nit: __ for static function used within the file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, originally i only proposed this convention for within CoreText/Graphics, given that we had a high incidence of both file-private and framework-private functions. Did we begin to use this more broadly?
} | ||
|
||
if (error) { | ||
*error = innerError ? [innerError retain] : nil; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
innerError ? [innerError retain] : nil; [](start = 33, length = 39)
does this matter, if the innerError is nil, retain would return nil?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mm, i guess that's probably fine, yeah
- (instancetype)init { | ||
if (self = [super init]) { | ||
self->_condition = [[NSCondition alloc] init]; | ||
self->_condition = [NSCondition new]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self->_condition [](start = 8, length = 16)
just use _condition, I almost confused myself thinking this was +2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is _condition really more clear than self->_condition?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be, given self.* isn't a syntax access of the instance variable directly. It would be confusing to use self-> which is a direct instance access (by passing the property)
In reply to: 111228615 [](ancestors = 111228615)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it wouldn't be a good choice to use self->, unless you have a specific reason to.
In reply to: 111229286 [](ancestors = 111229286,111228615)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally default to using self-> in inits, to guard against [super init] doing a replacement. That's not really possible here since the superclass is NSObject, so I'll change it, but I disagree that there needs to be a specific reason to use self->, especially since inheritance interactions aren't always this clear...
In reply to: 111229643 [](ancestors = 111229643,111229286,111228615)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⏲
@implementation NSURLConnectionTestHelper_OperationQueue | ||
- (instancetype)init { | ||
if (self = [super init]) { | ||
self->_operationQueue = [NSOperationQueue new]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self-> [](start = 7, length = 7)
here too
Fixes #2298