-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTRAIN_00681.eml
77 lines (63 loc) · 2.66 KB
/
TRAIN_00681.eml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
NoneNoneOn Apr 16, 2010, at 3:53 PM, Hamish Allan wrote:
> Hi,
>=20
> I'm rather puzzled by some behaviour I'm seeing, as explained by the
> comment in the following short category:
>=20
> @implementation NSPersistentStore (OTAdditions)
> - (NSNumber *)autoincrementingNumberForKey:(NSString *)key
> {
> NSNumber *number;
> @synchronized(self)
> {
> NSMutableDictionary *metadata =3D [[self metadata] =
mutableCopy];
>=20
> // need to copy and autorelease the number because the original
> // does not remain valid outside of the @synchronized block =
(why?!)
> number =3D [[[metadata objectForKey:key] copy] autorelease];
>=20
> if (!number)
> number =3D [NSNumber numberWithUnsignedLongLong:1];
> [metadata setValue:[NSNumber
> numberWithUnsignedLongLong:([number unsignedLongLongValue] + 1)]
> forKey:key];
> [self setMetadata:metadata];
> }
> return number;
> }
> @end
>=20
> The behaviour I'm seeing is as though the NSNumber returned by
> [metadata objectForKey:key] has been added to a special
> mini-autorelease pool scoped by the @synchronized block, whereas the
> autoreleased copy is added to the normal autorelease pool. At least, I
> assume the NSNumber is being deallocated, but symbolic breakpoints on
> -[NSNumber release] and -[NSNumber dealloc] remain in a pending state
> so I haven't been able confirm that.
>=20
> Can anyone tell me what's going on here?
Nothing related to @synchronized. Your problem is that you are acquiring =
an unretained pointer to an object, then doing something that releases =
the object behind your back.
number =3D [metadata objectForKey:key];
`number` now points to some object. Importantly, -objectForKey: just =
hands back the pointer, without doing the [[result retain] autorelease] =
dance. It's possible that the only thing that retained `number` is the =
`metadata` dictionary.
[metadata setValue:something forKey:key];
Now `metadata` has released `number`. It may be dead.
You need to be careful with -objectForKey: and -objectAtIndex: while you =
are mutating the container. Those methods avoid autorelease for =
performance, but (as you found) it's also less safe.
Your solution of copy+autorelease is correct. retain+autorelease might =
be better.=20
--=20
Greg Parker [email protected] Runtime Wrangler
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Objc-language mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/objc-language/mlsubscriber.tech%40csmining.org
This email sent to [email protected]