Skip to content
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

Merged
merged 6 commits into from
Apr 13, 2017

Conversation

ms-jihua
Copy link
Contributor

@ms-jihua ms-jihua commented Apr 7, 2017

- 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 #2298

    - 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) {
Copy link
Contributor Author

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;
}
Copy link
Contributor

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
Copy link
Contributor

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

Copy link
Contributor Author

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,

Copy link
Contributor Author

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) {
Copy link
Contributor

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

Copy link
Contributor

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];
Copy link
Contributor

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

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 {

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:

Copy link
Contributor Author

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() {

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.

Copy link
Contributor Author

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;

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;

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;

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.

Copy link
Contributor Author

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)];

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

Copy link
Contributor Author

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.");

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;

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?

Copy link
Contributor Author

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];

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?

Copy link
Contributor Author

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);

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.

Copy link
Contributor Author

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

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]

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) {
Copy link
Contributor

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()

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use NSRunLoopMode

Copy link
Contributor Author

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 :(

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.

Copy link
Contributor Author

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. ;;;;

Copy link
Contributor Author

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;
Copy link
Contributor

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?

Copy link
Contributor Author

@ms-jihua ms-jihua Apr 7, 2017

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
Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

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
Copy link
Contributor

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) {
Copy link
Contributor

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];
Copy link
Contributor

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

Copy link

@DHowett-MSFT DHowett-MSFT Apr 7, 2017

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.

Copy link
Contributor

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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't these overretain?

Copy link
Contributor Author

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree 😛

@msft-Jeyaram
Copy link
Contributor

// Copyright (c) 2016 Microsoft Corporation. All rights reserved.

nit: remove


Refers to: Frameworks/include/NSURLProtocolInternal.h:3 in 120e3ec. [](commit_id = 120e3ec, deletion_comment = False)

- (instancetype)init {
if (self = [super init]) {
self->_condition = [[NSCondition alloc] init];
Copy link
Contributor

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];
Copy link
Contributor

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?

Copy link
Contributor Author

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

+ (BOOL)canHandleRequest:(NSURLRequest*)request;
@property (readonly, copy) NSURLRequest* originalRequest;
@property (readonly, copy) NSURLRequest* currentRequest;
@property (readonly, copy) NSURLRequest* currentRequest STUB_PROPERTY;
Copy link
Contributor

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...

Copy link
Contributor

@msft-Jeyaram msft-Jeyaram left a 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;

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];

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

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());

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()?

Copy link
Contributor Author

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]];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commented code

Copy link
Contributor Author

@ms-jihua ms-jihua Apr 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, ty for catching

}

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

Copy link
Contributor Author

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!");

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);

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) {

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);

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?

Copy link
Contributor Author

@ms-jihua ms-jihua Apr 10, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. https://developer.apple.com/reference/foundation/nsurlconnection/1409722-unschedulefromrunloop?language=objc

"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;

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)

Copy link
Contributor Author

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) {

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();

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)

@ms-jihua
Copy link
Contributor Author

ping!

@ms-jihua
Copy link
Contributor Author

ping! last call @msft-Jeyaram @aballway @rajsesh-msft

Copy link
Contributor

@aballway aballway left a 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) {
Copy link
Contributor

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

Copy link
Contributor Author

@ms-jihua ms-jihua Apr 12, 2017

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;
Copy link
Contributor

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?

Copy link
Contributor Author

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

@msft-Jeyaram
Copy link
Contributor

// Copyright (c) 2016 Microsoft Corporation. All rights reserved.

still needs update


In reply to: 292643560 [](ancestors = 292643560)


Refers to: Frameworks/include/NSURLProtocolInternal.h:3 in 120e3ec. [](commit_id = 120e3ec, deletion_comment = False)

- (instancetype)init {
if (self = [super init]) {
self->_condition = [[NSCondition alloc] init];
self->_condition = [NSCondition new];
Copy link
Contributor

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.

Copy link
Contributor Author

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?

Copy link
Contributor

@msft-Jeyaram msft-Jeyaram Apr 12, 2017

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)

Copy link
Contributor

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)

Copy link
Contributor Author

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops im just wrong


In reply to: 111231093 [](ancestors = 111231093,111229643,111229286,111228615)

Copy link
Contributor

@msft-Jeyaram msft-Jeyaram left a 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];
Copy link
Contributor

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

@ms-jihua ms-jihua merged commit 4c6f2ed into microsoft:develop Apr 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants