{"action":"created","issue":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2702","labels_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2702/labels{/name}","comments_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2702/comments","events_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2702/events","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2702","id":73741909,"number":2702,"title":"_AFStateObserving Swizzling Implementation is Wrong","user":{"login":"fouvrai","id":700695,"avatar_url":"https://avatars.githubusercontent.com/u/700695?v=3","gravatar_id":"","url":"https://api.github.com/users/fouvrai","html_url":"https://github.com/fouvrai","followers_url":"https://api.github.com/users/fouvrai/followers","following_url":"https://api.github.com/users/fouvrai/following{/other_user}","gists_url":"https://api.github.com/users/fouvrai/gists{/gist_id}","starred_url":"https://api.github.com/users/fouvrai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fouvrai/subscriptions","organizations_url":"https://api.github.com/users/fouvrai/orgs","repos_url":"https://api.github.com/users/fouvrai/repos","events_url":"https://api.github.com/users/fouvrai/events{/privacy}","received_events_url":"https://api.github.com/users/fouvrai/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/labels/bug","name":"bug","color":"ff3333"},{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/labels/url%20session","name":"url session","color":"69B805"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/milestones/1","html_url":"https://github.com/AFNetworking/AFNetworking/milestones/2.5.4","labels_url":"https://api.github.com/repos/AFNetworking/AFNetworking/milestones/1/labels","id":1097138,"number":1,"title":"2.5.4","description":"","creator":{"login":"kcharwood","id":198768,"avatar_url":"https://avatars.githubusercontent.com/u/198768?v=3","gravatar_id":"","url":"https://api.github.com/users/kcharwood","html_url":"https://github.com/kcharwood","followers_url":"https://api.github.com/users/kcharwood/followers","following_url":"https://api.github.com/users/kcharwood/following{/other_user}","gists_url":"https://api.github.com/users/kcharwood/gists{/gist_id}","starred_url":"https://api.github.com/users/kcharwood/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kcharwood/subscriptions","organizations_url":"https://api.github.com/users/kcharwood/orgs","repos_url":"https://api.github.com/users/kcharwood/repos","events_url":"https://api.github.com/users/kcharwood/events{/privacy}","received_events_url":"https://api.github.com/users/kcharwood/received_events","type":"User","site_admin":false},"open_issues":1,"closed_issues":0,"state":"open","created_at":"2015-05-05T15:55:47Z","updated_at":"2015-05-07T14:34:08Z","due_on":null,"closed_at":null},"comments":21,"created_at":"2015-05-06T21:26:18Z","updated_at":"2015-05-10T20:29:03Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/pulls/2702","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2702","diff_url":"https://github.com/AFNetworking/AFNetworking/pull/2702.diff","patch_url":"https://github.com/AFNetworking/AFNetworking/pull/2702.patch"},"body":"The `_AFStateObserving` category on `NSURLSessionTask` was recently changed (2.5.3) to remove a `dispatch_once` block.  I'm not sure what the intent of this change was, but one of the side effects is that the swizzling gets run multiple times (for every initialized subclass of `NSURLSessionTask`) and effectively \"flip flops\" the implementations of the original methods with the swizzled methods.\r\n\r\nIf this gets called an odd number of times, it happens to work.  However, if it gets called an even number of times, the net result is that the swizzled methods are never run.\r\n\r\nIf I log the classes this method is called on, here's the result I see when I first use a data task:\r\n\r\n```\r\n2015-05-06 14:17:00.788 class=__NSCFLocalDataTask, taskClass=__NSCFLocalSessionTask\r\n2015-05-06 14:17:00.793 class=__NSCFLocalSessionTask, taskClass=__NSCFLocalSessionTask\r\n2015-05-06 14:17:00.795 class=NSURLSessionTask, taskClass=__NSCFLocalSessionTask\r\n2015-05-06 14:17:00.805 class=__NSCFLocalUploadTask, taskClass=__NSCFLocalSessionTask\r\n2015-05-06 14:17:00.809 class=NSURLSessionDataTask, taskClass=__NSCFLocalSessionTask\r\n```\r\n\r\nSo, this works fine for a while.  However, if I eventually _also_ use an upload task, I see this also:\r\n\r\n```\r\n2015-05-06 14:19:51.903 class=NSURLSessionUploadTask, taskClass=__NSCFLocalSessionTask\r\n```\r\n\r\nThis last call swizzles the methods a sixth time, resulting in `resume`/`suspend` being set back to their original implementations.  "},"comment":{"url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/comments/100696847","html_url":"https://github.com/AFNetworking/AFNetworking/pull/2702#issuecomment-100696847","issue_url":"https://api.github.com/repos/AFNetworking/AFNetworking/issues/2702","id":100696847,"user":{"login":"phoney","id":3106038,"avatar_url":"https://avatars.githubusercontent.com/u/3106038?v=3","gravatar_id":"","url":"https://api.github.com/users/phoney","html_url":"https://github.com/phoney","followers_url":"https://api.github.com/users/phoney/followers","following_url":"https://api.github.com/users/phoney/following{/other_user}","gists_url":"https://api.github.com/users/phoney/gists{/gist_id}","starred_url":"https://api.github.com/users/phoney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phoney/subscriptions","organizations_url":"https://api.github.com/users/phoney/orgs","repos_url":"https://api.github.com/users/phoney/repos","events_url":"https://api.github.com/users/phoney/events{/privacy}","received_events_url":"https://api.github.com/users/phoney/received_events","type":"User","site_admin":false},"created_at":"2015-05-10T20:29:03Z","updated_at":"2015-05-10T20:29:03Z","body":"@tangphillip Regardless if this issue is due to some defect in KVO, KVO is used by the OS and by thousands and thousands of apps on iOS and MacOS X. Fixing the KVO solution is a better idea than method swizzling. From the stack traces in the previous discussions it seems that this is a thread safety problem related to removing observers from transfers that end in failure. Pushing the removal of observers to a later time, and perhaps to the main thread would be a likely way to fix this."}}