2

Given this code:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in cookieStorage.cookies) {
    if (/* my specific condition that is true multiple times */) {
        [cookieStorage deleteCookie:cookie];
    }
}

This does not throw an exception, implying that the mutation of the cookie jar during the enumeration is safe. What I want to know is, why? Is this always going to be safe, or does it just happen to be safe due to some implementation detail that may change?

i_am_jorf
  • 53,608
  • 15
  • 131
  • 222

1 Answers1

2

Practical answer: the clue is in the header; cookies is defined as:

@property (readonly, copy) NSArray *cookies;

Per the Apple documentation, that "Copy Properties Maintain Their Own Copies", i.e. the cookies array is not the live storage, it is a copy. What you receive from it is a snapshot.

When you call deleteCookie, the new list of cookies is created and subsequent calls to cookies will return a then-up-to-date copy but the one you still have hold of from previously isn't affected.

In pure code terms, copy implies setCookies: (if it exists; it isn't publicly confirmed or denied) will take a copy of whatever is passed in. So if what was passed in was mutable it'll become immutable. So whatever you receive will be immutable. So it definitely won't mutate.

From either piece of reasoning, you are not mutating, and are not able to mutate, the actual thing you're iterating. You're mutating the cookie store but iterating through a copy of one piece of its contents.

Tommy
  • 99,986
  • 12
  • 185
  • 204
  • adding on a minor detail here--not only is `setCookies:` not publicly exposed, it actually doesn't exist at all. Setters for `readonly` properties are not synthesized by the compiler. – Morgan Chen Oct 29 '14 at 18:28
  • @MorganChen you'd need to check at runtime to be completely sure it doesn't exist; they may have redeclared without the `readonly` in a class extension. Or just written the setter themselves, of course. But, no, I shouldn't have spoken as though we know the setter exists. – Tommy Oct 29 '14 at 19:04
  • Good point @Tommy, my comment should say "may or may not exist". – Morgan Chen Oct 29 '14 at 19:07