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

Replace crashing KVO with manually method call #406

Closed
wants to merge 2 commits into from

Conversation

xilin
Copy link

@xilin xilin commented Sep 7, 2017

See the issue 390.
Same thing happened in AFNetworking (PR 2411 and 2702).
So I tried to do the same thing in PINRemoteImage using method swizzle instead of KVO.

@pinterest pinterest deleted a comment Sep 7, 2017
Copy link
Collaborator

@garrettmoon garrettmoon left a comment

Choose a reason for hiding this comment

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

Is it possible to use iOS 11's new session metrics instead of swizzling? I realize that wouldn't fix the issue for lower versions of the OS but they'll dwindle in population soon.

+ (void)load {
/**
Swizzle NSURLSessionTask in AFNetworking's way
See AFURLSessionManager.m in AFNetworking project for detail
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you mind adding a link to the issue: #390

Copy link
Author

Choose a reason for hiding this comment

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

Done.

_startTime = 0;
_endTime = 0;
[task addObserver:self forKeyPath:kPINURLSessionTaskStateKey options:0 context:nil];
+ (void)load {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if there's a way to avoid using load? This will increase startup time which I like to avoid as much as possible. Could we possibly make this PIN_setupSessionTaskObserver and make it a class method with a dispatch_once inside? Then put all the code within a dispatch_once?

Copy link
Author

Choose a reason for hiding this comment

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

I also prefer to avoid using of load, which is introduced for method swizzling. But I don't know how to update the PIN_startTime correctly instead of hooking resume method. In order to make method swizzling work correctly, I think load method cannot be avoid.

Do you think it's right if I add a new method call to update PIN_startTime manually after call of task's resume?

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
IMP classResumeIMP = method_getImplementation(class_getInstanceMethod(currentClass, @selector(resume)));
Method afResumeMethod = class_getInstanceMethod(currentClass, @selector(af_resume));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks like this code was copied from AFNetworking, I don't think their license allows that without also duplicating their license.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, it is. I could change to a new style if method swizzling is still needed.

@xilin
Copy link
Author

xilin commented Sep 8, 2017

Thanks for the information on iOS 11's new session metrics features. I haven't learned about it yet.
I'll try to catch up.

@workhardupc
Copy link

@garrettmoon which version will fix the crash?

@xilin
Copy link
Author

xilin commented Sep 14, 2017

So I decided to abandon method swizzling, and update time properties manually. As for session metrics features, I haven't given time to learn more about it. Sorry for that.

@ghost
Copy link

ghost commented Sep 14, 2017

🚫 CI failed with log

@ghost
Copy link

ghost commented Sep 14, 2017

🚫 CI failed with log

@xilin xilin changed the title Replace crashing KVO with method swizzling Replace crashing KVO with manually method call Sep 15, 2017
@xilin
Copy link
Author

xilin commented Sep 15, 2017

About the failure test testResume, I tried to run the test in my local machine. Even use the master branch of original PINRemoteImage I cannot pass the test. That's strange.

@ghost
Copy link

ghost commented Sep 15, 2017

🚫 CI failed with log

Copy link
Collaborator

@garrettmoon garrettmoon left a comment

Choose a reason for hiding this comment

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

I don't think this method will work because we can't guarantee a task will start when we request the system to start it. For example, if we configure the maximum number of connections to a given host to be 2 and then we resume 5 tasks, only 2 will start right away, but all 5 will be marked as started :(

@@ -106,7 +105,7 @@ - (void)scheduleDownloadsIfNeeded
NSURLSessionDataTask *task = [queue firstObject];
[queue removeObjectAtIndex:0];
[task resume];

[task PIN_updateStartTime];
Copy link
Collaborator

Choose a reason for hiding this comment

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

So sadly, this isn't when the system will guarantee starting the task :( It's when we ask it to, but the system can choose to delay starting it…

Copy link
Author

Choose a reason for hiding this comment

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

So method swizzling will not work neither, since it will update the start time immediately when resume is called.

@garrettmoon
Copy link
Collaborator

@xilin that test only passes on slow network and is unreliable, sorry! Ignore that test and I'll make sure to rerun the CI until it passes before we merge.

@xilin
Copy link
Author

xilin commented Sep 19, 2017

It seems that KVO is the best option for the feature currently. I'll close the PR and see if there is the other way to do it right.

@xilin xilin closed this Sep 19, 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.

3 participants