Re: Properties, Attributes and Retain+Autorelease

2011-06-30 Thread Markus Hanauska

On 2011-06-29, at 21:50 , Quincey Morris wrote:

 You're looking for provable correctness. That's laudable, and will probably 
 mean that you keep all of your fingers. But you'll still end up in the 
 emergency room -- in your case it will be for a stress-induced ulcer. :)

My university professor once said:
If you write code that other people will or have to use and they are supposed 
to use it without having to read your source code first, implement every 
method/function in such a way as if everybody out there has only one goal: 
Breaking it! Either by feeding completely absurd input parameters to it or by 
calling your methods/functions any completely absurd order or combination you 
can ever think of.

 Excuse me for saying this, but I think this particular discussion has gone on 
 too long.

The discussion was going on for hardly 9 hours when you wrote that.

 You're not going to get any new answers to your questions, because there are 
 no answers to give beyond what's already been said.

Actually I think I didn't get answers to those questions, because nobody knew 
the answers and instead of arguing why the answers don't matter, people could 
have just admitted that they don't know the answers either. Anyway, I think I 
figured out those answers all by myself in the meantime.

Kind regards,
Markus

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease (SOLVED)

2011-06-30 Thread Markus Hanauska

Since nobody was able to provide real answers to my questions, I wrote some 
dummy code to find out as much about that issue as possible.  Here are the 
results:

Remember, I listed the following cases:

   a) retain
   b) retain, nonatomic
   c) copy
   d) copy, nonatomic  
   e) assign
   f) assign, nonatomic


And I gave sample code for a) and b) already:

 a) retain
 
 - (id)value
 {
   id res;
   [_magic_lock lock];
   res = [value retain];
   [_magic_lock unlock];
   return [res autorelease];
 }
 
 - (void)setValue:(id)aNewValue
 {
   [_magic_lock lock];
   if (aNewValue != value) {
   [value release];
   value = [aNewValue retain];
   }
   [_magic_lock unlock];
 }
 
 
 b) retain, nonatomic
 
 - (id)value
 {
   return value;
 }
 
 - (void)setValue:(id)aNewValue
 {
   if (aNewValue != value) {
   [value release];
   value = [aNewValue retain];
   }
 }

As far as my testing goes, the sample code seems to be pretty close to what's 
really going on, though Apple is probably doing all this stuff on a much lower 
level, possibly highly optimized and thus much faster than the code above ever 
could. Here's how the code for the other cases would look like:

c) copy

The getter equals case a)

- (void)setValue:(id)aNewValue
{
[_magic_lock lock];
if (aNewValue != value) {
[value release];
value = [aNewValue copy];
}
[_magic_lock unlock];
}


d) copy, nonatomic

The getter equals case b)

- (void)setValue:(id)aNewValue
{
if (aNewValue != value) {
[value release];
value = [aNewValue copy];
}
}


e) assign

- (id)value
{
id res;
[_magic_lock lock];
res = value;
[_magic_lock unlock];   
return res;
}

- (void)setValue:(id)aNewValue
{
[_magic_lock lock];
value = aNewValue;
[_magic_lock unlock];
}


f) assign, nonatomic

- (id)value
{
return value;
}

- (void)setValue:(id)aNewValue
{
value = aNewValue;
}


Apple may optimize case e) to become case f) in case reading/writing value is 
an atomic operation anyway, e.g. setting a 32 bit value on a 32 bit CPU is 
guaranteed to be atomic already through the compiler. However, setting a 64 bit 
value on a 32 bit CPU (or a 64 bit CPU running in 32 bit mode) is not atomic 
for example, just like setting a 8/16 bit value on a 32/64 bit CPU may not be 
atomic (this depends on CPU, e.g. some operations are atomic on Intel CPUs that 
used to be not atomic on PPC CPUs).

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska
Unfortunately the documentation on properties is really inadequate since Apple 
fails to provide pseudo-code for every possible attribute combination. E.g. 
the nonatomic attribute has a couple of dangerous side effects that seem to be 
unknown even to developers using properties for years. The documentation should 
provide sample code for the following attribute combinations:

a) retain
b) retain, nonatomic
c) copy
d) copy, nonatomic  
e) assign
f) assign, nonatomic

Let me show you which dangerous side effects I'm talking about by providing 
sample code for the cases a) and b) as I would have implemented them:

a) retain

- (id)value
{
id res;
[_magic_lock lock];
res = [value retain];
[_magic_lock unlock];
return [res autorelease];
}

- (void)setValue:(id)aNewValue
{
[_magic_lock lock];
if (aNewValue != value) {
[value release];
value = [aNewValue retain];
}
[_magic_lock unlock];
}


b) retain, nonatomic

- (id)value
{
return value;
}

- (void)setValue:(id)aNewValue
{
if (aNewValue != value) {
[value release];
value = [aNewValue retain];
}
}

Okay, you can argue about the implementation details here, e.g. the if-clause 
in the setter is optional, I could also implement a setter like this:

[aNewValue retain];
[value release];
value = aNewValue;

This will work fine, even if aNewValue equals value, but it causes an 
unnecessary retain/release and those are certainly not the fastest operations, 
since they will either involve locks (rather expensive) or at least atomic 
operations (still somewhat expensive and have a negative impact on overall 
system performance of multicore systems, since they might for example have to 
block the CPU bus to guarantee atomic access across all cores and that means 
other cores are not be able to access main memory during such an operation).

The code above already reveals a huge problem: When I read the terms atomic 
and nonatomic, I certainly expect one to use a lock (or at least atomic 
operations of some kind) and the other one not. This is no big surprise. What 
is a big surprise though, is the fact that one version extends the lifetime of 
an object beyond the lifetime of its owner, while the other one won't. This 
has *NOTHING* to do with wether an operation is atomic or not!

E.g. consider the following code:

ObjectCreator oc = [[ObjectCreator alloc] init];
id value = [oc value];
[oc release];
[value someMethod];

In case a) this will work just fine, however in case b) this code might *CRASH* 
my app! This is a fact not obvious to many developers. The nonatomic attribute 
makes getters behave like getters of NSArray or NSDictionary, which do not 
extend lifetime of returned objects beyond their own lifetime, while normal, 
atomic getters do the retain+autorelease dance. This is something that should 
be written on the very top of Apple's doc in bold letters with a font size of 
18 pt.

Unfortunately a) and b) are the only obvious cases, already c) and d) are not 
really explained in detail. One thing that seems obvious is c) and d) use 
copy instead of retain in their setters. However, what about getters? Do 
they use copy there as well? Do they use retain+autorelease? Do they just 
return the values? Are the getters equal to the getters a) and b) for copy 
properties?

Similar questions arise for e) and f). E.g. will e) return the values 
retain+autorelease, even though the setters don't use retain? And how does 
nonatomic make any difference for assign properties? Assigning a pointer is 
guaranteed to be atomic anyway by the complier, at least for 32 bit pointers on 
i386 architecture when using GCC. I guess the same holds true for 64 bit 
pointers on x86_64 architecture (so I had to re-read the GCC specification to 
ensure that fact). Is the nonatomic attribute ignored for assign properties?

These open questions are what drives me away of using properties, since when I 
write my getter/setters myself, I know at least the answers to all those 
questions and the answers will not change either (contrary to the answers for 
properties, that might change whenever Apple releases a new Objective-C 
language specification).

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Fritz Anderson
On 29 Jun 2011, at 5:53 AM, Markus Hanauska wrote:

 The code above already reveals a huge problem: When I read the terms atomic 
 and nonatomic, I certainly expect one to use a lock (or at least atomic 
 operations of some kind) and the other one not. This is no big surprise. What 
 is a big surprise though, is the fact that one version extends the lifetime 
 of an object beyond the lifetime of its owner, while the other one won't. 
 This has *NOTHING* to do with wether an operation is atomic or not!
 
 E.g. consider the following code:
 
   ObjectCreator oc = [[ObjectCreator alloc] init];
   id value = [oc value];
   [oc release];
   [value someMethod];
 
 In case a) this will work just fine, however in case b) this code might 
 *CRASH* my app! This is a fact not obvious to many developers. The nonatomic 
 attribute makes getters behave like getters of NSArray or NSDictionary, 
 which do not extend lifetime of returned objects beyond their own lifetime, 
 while normal, atomic getters do the retain+autorelease dance. This is 
 something that should be written on the very top of Apple's doc in bold 
 letters with a font size of 18 pt.
 
 Unfortunately a) and b) are the only obvious cases, already c) and d) are not 
 really explained in detail. One thing that seems obvious is c) and d) use 
 copy instead of retain in their setters. However, what about getters? 
 Do they use copy there as well? Do they use retain+autorelease? Do they 
 just return the values? Are the getters equal to the getters a) and b) for 
 copy properties?
 
 Similar questions arise for e) and f). E.g. will e) return the values 
 retain+autorelease, even though the setters don't use retain? And how does 
 nonatomic make any difference for assign properties? Assigning a pointer 
 is guaranteed to be atomic anyway by the complier, at least for 32 bit 
 pointers on i386 architecture when using GCC. I guess the same holds true for 
 64 bit pointers on x86_64 architecture (so I had to re-read the GCC 
 specification to ensure that fact). Is the nonatomic attribute ignored for 
 assign properties?
 
 These open questions are what drives me away of using properties, since when 
 I write my getter/setters myself, I know at least the answers to all those 
 questions and the answers will not change either (contrary to the answers for 
 properties, that might change whenever Apple releases a new Objective-C 
 language specification).

Your conjectured implementations are just that — conjecture. Apple may be (and 
probably is) using methods more primitive than retain/release/autorelease. It 
may (probably has, and very probably will) change the implementation between 
point releases of the operating system. 

Your confusions and speculations become moot when you follow the rules: If you 
want to keep something, retain it. That covers all the code you suppose Apple 
wrote, as well as all the code Apple did write.

My instincts, too, rebel at value, in your example, going away. I'd like 
objects to behave like scalar values, or like C++ local objects. They don't. 
The memory-management rules say they don't. I myself cheat, but even I don't 
expect an object to survive the explicit destruction of its container.

— F

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska

On 2011-06-29, at 13:58 , Fritz Anderson wrote:

  Apple may be (and probably is) using methods more primitive than 
 retain/release/autorelease. It may (probably has, and very probably will) 
 change the implementation between point releases of the operating system. 

This is absolutely obvious, but you are failing the point. I don't personally 
care how Apple really implements it, I just would like to see which code 
would pretty much lead to exactly the same behavior. That this code might be 
entirely different than the real code is of no importance to anyone, I guess. 
And of course using properties is in theory a good thing, since I bet most of 
them is implemented in plain-C, possible even some hand written assembly code, 
and thus certainly faster and more effective than any code you could ever write 
yourself using high level Objective-C.

However I cannot use something correctly if there is no documentation of how it 
actually works. E.g. the question how nonatomic influences assign properties 
(if it does influence them at all!) is a critical and absolutely valid 
question, especially if it has similar *UNEXPECTED* side effects as it has for 
retain properties (and you cannot avoid assign properties entirely, otherwise 
you can get circular references and thus leaking memory).

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Matt Neuburg
On Wed, 29 Jun 2011 12:53:26 +0200, Markus Hanauska hanau...@equinux.de said:
E.g. consider the following code:

   ObjectCreator oc = [[ObjectCreator alloc] init];
   id value = [oc value];
   [oc release];
   [value someMethod];


We actually had something very like this discussion here already recently:

http://lists.apple.com/archives/cocoa-dev/2011/Mar/threads.html

(Look at the thread titled NSAttributedString crashes.)

As I said then, Ownership is *never* something you are magically given. It is 
always something that you must take if you want it. Perhaps that answer isn't 
very satisfactory, but at least it provides a philosophy that covers the case. 
As Andy Lee says in that same thread, We've been conditioned to think we have 
extra persistence time at least up to the next run loop iteration, but (I 
think he's implying) this conditioning is specious and serves only to make us 
lazy. To put it another way: ObjectCreator's value method is opaque; to 
pretend that you *know* its memory-management policy is really just a case of 
programming by guesswork. m.

--
matt neuburg, phd = m...@tidbits.com, http://www.apeth.net/matt/
A fool + a tool + an autorelease pool = cool!
Programming iOS 4!
http://www.apeth.net/matt/default.html#iosbook___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska

On 2011-06-29, at 18:09 , Matt Neuburg wrote:

 As I said then, Ownership is *never* something you are magically given.

Since when do you have to be owner of an object to be allowed to interact with 
it? 
This contradicts pretty much everything Apple has ever documented about 
Cocoa/Obj-C.

Following your reasoning, Apple has to re-design Cocoa and re-write all guides 
and sample code, since no method should ever return a retain+autorelease 
result, instead all code must always follow the (currently inexistent  rule): 
An object returned by another object is only guaranteed to live as long as the 
object lives that returned it. To extend its lifetime you always have to retain 
the object.

Right now this is only the case for collection classes and it is in fact *so 
special* that Apple *explicitly* points out this fact in their documentation. 
And to be honest, Apple only implemented them that way for performance reasons 
- if retain+autorelease was pretty much for free, I bet Apple had even used 
that for return values of collection classes; since that is what they do for 
pretty much all other classes. E.g. the description method of an object 
always returns a NSString that will for sure stay alive, even if you kill the 
object after calling description on it - I have never seen an implementation 
of description which hasn't. Nobody would seriously consider retaining this 
string.

However, you are also missing my primary point: I have no problem with the fact 
that an object won't live longer than it's parent; this is just something 
that nonatomic doesn't tell me. Nonatomic tells me that the operation is not 
atomic, fine, but I don't expect it to influence object live duration; those 
are two completely different things not related to each other. Also it's pretty 
much funny how both answers I received so far concentrated on this remark, but 
none of them answered a single of the various questions I have asked in my mail 
(and *THOSE* were my primary points). Now that I have learned what nonatomic 
means to retain properties, it would be nice to know what nonatomic means to 
assign and copy properties for example.

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Kyle Sluder
On Wed, Jun 29, 2011 at 10:08 AM, Markus Hanauska hanau...@equinux.de wrote:
 Since when do you have to be owner of an object to be allowed to interact 
 with it?

You're holding on to the result of -value. Therefore you need an
ownership reference to it.

This is something Cocoa programmers have needed to worry about
forever. The canonical example is this:

id o = [myArray objectAtIndex:0];
[myArray release];
NSLog(@%@, [o description]); // -- CAN CRASH HERE

Unless you know you have ownership of the object (directly by
retaining it, or indirectly by owning something else that has an
owning reference to the object), you can't assume your pointer to the
object is valid.

 This contradicts pretty much everything Apple has ever documented about 
 Cocoa/Obj-C.

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html%23//apple_ref/doc/uid/TP40004447-1000922-BABBFBGJ

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska

On 2011-06-29, at 18:09 , Matt Neuburg wrote:

 As I said then, Ownership is *never* something you are magically given.

Actually I have to correct my previous statement, since it is incorrect. I said:

Following your reasoning, Apple has to re-design Cocoa and re-write all guides 
and sample code, since no method should ever return a retain+autorelease 
result, instead all code must always follow the (currently inexistent  rule): 
An object returned by another object is only guaranteed to live as long as the 
object lives that returned it. To extend its lifetime you always have to retain 
the object.

However, this is far from true. Even if the object stays alive and even if you 
don't call a setter for this property (e.g. it might even be a readonly 
property), any other call to the parent might cause it to release the previous 
returned object. So I always would have to retain any object I received through 
any method call you can think of before using it. Even if I just want to pass 
it on I have to retain it:

id value = [someObject value];
[value retain];
[someOtherObject setValue:value];
[value release];

Why? How can I know that someOtherObject won't have a reference to someObject 
and that calling setValue of someOtherObject won't make a call to someObject 
which causes some object to release the value it returned before, without 
someOtherObject having a chance to retain it? Since someOtherObject cannot know 
from where it received the value and it certainly won't expect this value to 
go away just because it calls some method of someObject. Does that make any 
sense? If not, maybe with some more code. Assume that my code is only like that:

[someOtherObject setValue:[someObject value]];

Pretty typical code you find in millions of source files. However, now consider 
someOtherObject has a reference to someObject and part of their implementation 
will look like this:

// someObject

- (id)value
{
return value;
}

- (void)doSomething
{
// ...
[value release];
value = ...;
/ /...
}

// someOtherObject

- (void)setValue:(id)aValue
{
[someObject doSomething];
if (value == aValue) return;

[value release];
value = [aValue retain]; // --- BANG, CRASH
}

So I would have in fact to always retain any value before doing anything with 
it, even when I just want to pass it on! Think about it.

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska

On 2011-06-29, at 19:17 , Kyle Sluder wrote:

 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html%23//apple_ref/doc/uid/TP40004447-1000922-BABBFBGJ


Yes, it talks about certain*exceptions*, and you are right, one of them is in 
fact destroying the parent, so I'm wiling to accept that you must not rely upon 
an object to stay alive longer than its parent.  However, have you also read 
the top paragraph?

Cocoa’s ownership policy specifies that received objects should typically 
remain valid throughout the scope of the calling method. It should also be 
possible to return a received object from the current scope without fear of it 
being released. It should not matter to your application that the getter method 
of an object returns a cached instance variable or a computed value. What 
matters is that the object remains valid for the time you need it.

This principle is violated by a getter returning an object that is not 
retain+autorelease, since even without destroying the parent the returned 
object might go away. As pointed out in my other mail:

[someOtherObject setValue:[someObject value]];

// someObject

- (id)value
{
return value;
}

- (void)doSomething
{
// ...
[value release];
value = ...;
/ /...
}

// someOtherObject

- (void)setValue:(id)aValue
{
[someObject doSomething];
if (value == aValue) return;

[value release];
value = [aValue retain]; // --- BANG, CRASH
}

It violates the policy stated above, even though this is *no collection* class 
and the parent has *not* been released. Neither of the two exception cases 
mentioned on the liked page above has been met!

If that was allowed, one would have to write code like this:

id value = [someObject value];
[value retain];
[someOtherObject setValue:value];
[value release];

And nobody seriously writes such code.

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Eeyore
Still learning Cocoa myself, so hoping to be corrected if I'm wrong.

On Jun 29, 2011, at 10:39 AM, Markus Hanauska wrote:

 Cocoa’s ownership policy specifies that received objects should typically 
 remain valid throughout the scope of the calling method. It should also be 
 possible to return a received object from the current scope without fear of 
 it being released. It should not matter to your application that the getter 
 method of an object returns a cached instance variable or a computed value. 
 What matters is that the object remains valid for the time you need it.
 
 This principle is violated by a getter returning an object that is not 
 retain+autorelease, since even without destroying the parent the returned 
 object might go away. As pointed out in my other mail:
 

I guess I'm not sure what the debate is. Are you questioning whether Apple's 
code honors the agreement? If you find an instance where Apple's code is 
actually violating this agreement, then you should file a bug. Otherwise, you 
should probably work under the assumption that all of Apple's getters other 
than those specifically excluded will retain/autorelease and that synthesized 
getters will also follow a retain/autorelease pattern.

 // someObject
 
   - (id)value
   {
   return value;
   }
   
   - (void)doSomething
   {
   // ...
   [value release];
   value = ...;
   / /...
   }
 // someOtherObject
 
   - (void)setValue:(id)aValue
   {
   [someObject doSomething];
   if (value == aValue) return;
 
   [value release];
   value = [aValue retain]; // --- BANG, CRASH
   }


On the other hand, if you are writing your own getters and setters, of course 
you can break the contract (as someObject does here). Matt Gallagher writes 
about this in 
http://cocoawithlove.com/2010/06/assign-retain-copy-pitfalls-in-obj-c.html 
where he says that he typically does not follow a retain/autorelease but is 
aware that the result would be more correct with them. If you get the 
BANG-CRASH and are the author of someOtherObject, you should submit a bug to 
someObject's author and then put a workaround in place, two possible examples:

 [someOtherObject setValue: [[[someObject value] retain] autorelease]]; // 
 retain/autorelease required due to bug in [someObject value]


or possibly, use a category to extend someObject to provide a safe getter as a 
work-around

 - (id)safeValue
 {
 return [[[self value] retain] autorelease];
 }

and then never use value, but use safeValue instead

 [someOtherObject setValue: [someObject safeValue]];

Both workarounds would be removed when the author of someObject gets his/her 
act together (either by retain/autoreleasing in the getter or by autoreleasing 
in doSomething).

Aaron

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Kyle Sluder
On Wed, Jun 29, 2011 at 10:39 AM, Markus Hanauska hanau...@equinux.de wrote:
 Yes, it talks about certain*exceptions*, and you are right, one of them is in 
 fact destroying the parent, so I'm wiling to accept that you must not rely 
 upon an object to stay alive longer than its parent.  However, have you also 
 read the top paragraph?

 Cocoa’s ownership policy specifies that received objects should typically 
 remain valid throughout the scope of the calling method. It should also be 
 possible to return a received object from the current scope without fear of 
 it being released. It should not matter to your application that the getter 
 method of an object returns a cached instance variable or a computed value. 
 What matters is that the object remains valid for the time you need it.

 This principle is violated by a getter returning an object that is not 
 retain+autorelease, since even without destroying the parent the returned 
 object might go away. As pointed out in my other mail:

Yes, but all of this is already well-known. FWIW, nothing about atomic
guarantees that the object is returned retained/autoreleased.

All of your criticisms are valid, but they're the precise criticisms
that ARC addresses.

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Markus Hanauska

On 2011-06-29, at 20:08 , Matt Neuburg wrote:

 On Jun 29, 2011, at 10:39 AM, Markus Hanauska wrote:
 
 If that was allowed, one would have to write code like this:
 
  id value = [someObject value];
  [value retain];
  [someOtherObject setValue:value];
  [value release];
 
 That's silly. You didn't release someObject this time, so now there's no need 
 to worry about the lifetime of value.

That's assuming that setValue of someOtherObject is not doing anything in the 
system (call a method, maybe posting a notification, altering a singleton or a 
global variable, etc.) which may cause value to be released... and I can not 
guarantee so, unless I know for sure that value is either retained or at least 
retain+autorelease. Since almost all Cocoa objects from Apple will return value 
retain+autorelease, this can indeed not happen, but hey, it wasn't me claiming 
it's perfectly okay that nonatomic getters don't return objects 
retain+autorelease and that this will not break anything, because it's totally 
okay if objects you don't own unexpectedly cease to live. I posted code that 
showed how this can easily happen, haven't you read it? Shall I make a 
compilable project for you, so you can see it crashing yourself?

I personally think a getter should always return objects retain+autorelease and 
that no matter if it is atomic or not. This is certainly not the best thing 
performance-wise, but it is the safest way to return values in a complex system 
where you don't know which implications simple method calls really have under 
the hood. E.g. you can skip the retain+autorelease dance when you use private 
objects in your own framework that you don't expose to the public or properties 
not visible outside your framework (they are just for internal use), but for 
all methods you are going to expose only the retain+autorelease dance 
guarantees safety.

Which brings me back to my original questions, e.g. whether an assign 
property returns values retain+autorelease when atomic and not when 
nonatomic... or does it always return the value not retain+autorelease since 
assign properties ignore the nonatomic flag anyway, since there is nothing to 
be done, they are atomic anyway by definition.

Kind regards,
Markus___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Properties, Attributes and Retain+Autorelease

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 12:08, Markus Hanauska wrote:

 I personally think a getter should always [snip] ...

You know, in the Cocoa world, we play with live ammo. When we are handed a 
pointer without ownership, we go ahead and use it for a while without taking 
ownership. For as long as we do that, it's ticking and if we run out of time 
it's going to explode.

What keeps us from losing our thumbs, most of the time, are ... well ... rules 
of thumb, supported by best practices for things like returning object values 
from property getters. It's all fragile, but trips to the emergency room are 
very infrequent if we take just a little bit of care.

You're looking for provable correctness. That's laudable, and will probably 
mean that you keep all of your fingers. But you'll still end up in the 
emergency room -- in your case it will be for a stress-induced ulcer. :)

 Which brings me back to my original questions, e.g. whether an assign 
 property returns values retain+autorelease when atomic and not when 
 nonatomic... or does it always return the value not retain+autorelease since 
 assign properties ignore the nonatomic flag anyway, since there is nothing 
 to be done, they are atomic anyway by definition.

TBH, if you think the purpose of 'atomic' is to protect the retain/release 
behavior of instance variables, I think you're dead wrong. It's to protect the 
integrity of the instance variable value, which is potentially corruptible in 
multi-threaded use of setters. If the current synthesized atomic setter 
implementation behavior is to atomicize the retain count adjustment too, that's 
nice, but not essential, since retain/release are themselves atomic. As you've 
spent some time pointing out, the issues with retain counts exist at a higher 
level than atomicity.

That's also true of thread safety. The real issues are almost all at a higher 
level than atomicity.

Excuse me for saying this, but I think this particular discussion has gone on 
too long. You're not going to get any new answers to your questions, because 
there are no answers to give beyond what's already been said.


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com