Re: Assuring KVO compliance.

2015-04-07 Thread Quincey Morris
On Apr 7, 2015, at 09:05 , Alex Zavatone z...@mac.com wrote:
 
 Gremlins, I think.

No, something, but not that.

Enums are a C thing, not even Obj-C. They are, for all intents and purposes, an 
int of some size and signedness chosen by the compiler. So, the enum part of 
this is a red herring. The reason that changing the enum definition made a 
difference is, presumably, that it changed the way things were arranged in 
memory, and that by chance caused your actual problem to do something harmless 
instead of harmful.

Your actual error was this:

 delegate.app_idle_state = APP_State_Waiting;

 Thread1: EXC_BAD_ACCESS (code=1,address = 0x003f8f3)

and you were mislead by the word “access” to think this had something to do 
with accessing the property. Actually, EXC_BAD_ACCESS means an invalid pointer 
to memory.

You can’t tell which pointer, exactly, without looking at the backtrace to see 
exactly where execution was at the time of the exception. If it’s in the line 
of code that assigns the app state, the exception probably means that 
‘delegate’ is invalid, not the attempt to change the property.

So, you need to try to make the EXC_BAD_ACCESS happen again, and take a harder 
look at what’s going on at that point, ideally using the debugger at a 
breakpoint on the exception. You may have a memory management error relating to 
the delegate object — delegate object references are often kept unretained, 
which is prone to errors — or a thread safety issue.



___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Assuring KVO compliance.

2015-04-07 Thread Roland King

 On 7 Apr 2015, at 23:12, Alex Zavatone z...@mac.com wrote:
 
 To answer my own question, changing the enum to an NSInteger backed NS_Enum 
 resulted in no more bad access exceptions from other chunks of code 
 attempting to change the APP_State property.
 
 typedef NS_ENUM(NSInteger, APP_State) {
APP_State_Normal = 0,
APP_State_Expired = 1,
APP_State_Waiting = 2
 };
 
 Changing the atomicity of the exposed property had no effect on whether the 
 exception was issued or not.
 
 Hope this helps someone.
 
 Alex Zavatone
 

I was just looking at some of my own code because I’m pretty sure I use enums 
all the time in properties which are KVO and observe them and update them, and 
I’ve never once had to mess around with NS_ENUM to make them work. 

And indeed I found 4 examples quite quickly, all of which look very much like 
your original code, a typedef’ed enum used as a property. 

So I really don’t know where your bad accesses were coming from. 

This was all ObjC right ? 

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Assuring KVO compliance.

2015-04-07 Thread Alex Zavatone
To answer my own question, changing the enum to an NSInteger backed NS_Enum 
resulted in no more bad access exceptions from other chunks of code attempting 
to change the APP_State property.

typedef NS_ENUM(NSInteger, APP_State) {
APP_State_Normal = 0,
APP_State_Expired = 1,
APP_State_Waiting = 2
};

Changing the atomicity of the exposed property had no effect on whether the 
exception was issued or not.

Hope this helps someone.

Alex Zavatone



On Apr 7, 2015, at 10:04 AM, Alex Zavatone wrote:

 I've read Apple's docs on assuring KVO/KVC compliance, but in this particular 
 situation, I'd appreciate someone explaining what I'm not getting here if 
 it's anything obvious.
 
 I think what I'm asking is how to convert code that has a state exposed as a 
 (nonatomic, readwrite) property of a typedef-ed enum so that it can be 
 observed by KVO.
 
 The code that I've inherited has an enum (not an NSEnum) that represents the 
 app's connected state, 0, 1 or 2.
 
 This enum is then typedef-ed and then exposed as a property through @property 
 (nonatomic, readwrite) 
 
 This property is within the AppDelegate and is referred to and set throughout 
 the app.
 
 
 enum APP_State {
APP_State_Normal = 0,
APP_State_Expired = 1,
APP_State_Waiting = 2
 };
 typedef enum APP_State APP_State;
 
 @property (nonatomic, readwrite) APP_State app_idle_state;
 
 
 So, I want to set up an approach to monitor this state and set a readout 
 graphic based upon the state's value. I had assumed that KVO would be the 
 path of least overhead and allow a rather self contained little class to 
 handle this without any nasty polling.  
 
 Within a new class, I added an observer to the APP_State property on the 
 appDelegate and this operates as expected, but adding the KVO will trigger an 
 EXC_BAD_ACCESS when attempting to change the app_idle_state enum property 
 within another class that accesses that property in the delegate.
 
 Specifically, this:
 
 delegate.app_idle_state = APP_State_Waiting;
 
 Results in this:
 Thread1: EXC_BAD_ACCESS (code=1,address = 0x003f8f3)
 
 
 First of all, I've never seen enum being attempted to be exposed like this 
 (would making this an NS_ENUM help?).
 
 Also, I certainly was expecting *something* to go wrong here, but not causing 
 bad access exceptions elsewhere when code in another class attempts to set 
 the value of the property (since its property was set to readwrite).
 
 Changing the property declaration to atomic seems to be more correct in that 
 we don't want any other operation to happen on it, but that doesn't doesn't 
 affect whether or not an EXC_BAD_ACCESS.
 
 Or I could be walking down the wrong path entirely and should just poll for 
 the value or have a notification of a state change be sent to the monitoring 
 class.
 
 
 Thoughts?
 
 Thanks in advance, 
 Alex Zavatone
 ___
 
 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:
 https://lists.apple.com/mailman/options/cocoa-dev/zav%40mac.com
 
 This email sent to z...@mac.com


___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Assuring KVO compliance.

2015-04-07 Thread Alex Zavatone
Thanks Roland. 

Yeah, me neither, but this is inherited code where the previous guys obviously 
come from a java background and have done things in a manner I'm not accustomed 
to.  In this project, refactoring properties and methods in many classes 
actually causes Xcode to tell me I'd be better off handling it manually.  Never 
seen that before.

What doesn't sit right on this BAD_ACCESS problem is why did adding an 
observer cause other code to cause an exception and OK, the exception is 
gone, but do I really understand why it's gone and should this change have 
actually fixed it?

I'm assuming that the bad access is on the setting of the property within 
another class.  I'm assuming that the way the enum is declared and exposed is 
where the problem is and that is causing the exception.  Where its value is 
being set is where the debugger stops and tells me the exception is coming from.

What felt really odd to me was that simply adding an observer to a property in 
one class caused other code which set the property to trigger the exception to 
be thrown.  

However…

all of the classes in this iOS project have their ivars defined in their 
interfaces and then properties created for all of them and occasionally 
synthesizing the properties manually.  

I think we all stopped doing this in 2012 and I'm not going to address all of 
this until I know the product better.  

What this leads to though is a case of OK, I'm going to believe the debugger 
and try to make sure I address KVO/KVC compliance on the observed and make sure 
that the property is about to be observed and changed by multiple sources.  

So, I tried what I thought would be good practices.  Make sure the enum is 
backed by modern and KVC compliant approaches even though properties exposed 
through @synthesize should be KVO compliant, in case the way this property is 
exposed isn't.  For example, due to the way the code is set up, what if the 
property being changed isn't the property I think it is, but the ivar instead?

I didn't change the way the property is @synthesized (still manually), I did 
change the property's atomicity to atomic without affecting the error, the only 
changes I did make were to use NS_Enum and declare the enum type as NSInteger.

In fact, a quick test changing the type of the NS_ENUM from NSInteger back to 
int doesn't cause the BAD_ACCESS to reappear.

I hate to mark something this core as I don't know why but it works, but I 
don't know but it works.

Gremlins, I think.

Thanks for taking the time to eyeball this.
Alex Zavatone



On Apr 7, 2015, at 11:32 AM, Roland King wrote:

 
 On 7 Apr 2015, at 23:12, Alex Zavatone z...@mac.com wrote:
 
 To answer my own question, changing the enum to an NSInteger backed NS_Enum 
 resulted in no more bad access exceptions from other chunks of code 
 attempting to change the APP_State property.
 
 typedef NS_ENUM(NSInteger, APP_State) {
APP_State_Normal = 0,
APP_State_Expired = 1,
APP_State_Waiting = 2
 };
 
 Changing the atomicity of the exposed property had no effect on whether the 
 exception was issued or not.
 
 Hope this helps someone.
 
 Alex Zavatone
 
 
 I was just looking at some of my own code because I’m pretty sure I use enums 
 all the time in properties which are KVO and observe them and update them, 
 and I’ve never once had to mess around with NS_ENUM to make them work. 
 
 And indeed I found 4 examples quite quickly, all of which look very much like 
 your original code, a typedef’ed enum used as a property. 
 
 So I really don’t know where your bad accesses were coming from. 
 
 This was all ObjC right ? 
 

___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Assuring KVO compliance.

2015-04-07 Thread Jens Alfke

 On Apr 7, 2015, at 7:04 AM, Alex Zavatone z...@mac.com wrote:
 
 The code that I've inherited has an enum (not an NSEnum) that represents the 
 app's connected state, 0, 1 or 2.

There’s no difference. NS_ENUM is just a macro that defines a C enum, but uses 
some newer (C99?) syntax to specify the integer size that the enum should use. 
(Without that, if you just define a plain enum its size will be sizeof(int), 
IIRC.)

 Results in this:
 Thread1: EXC_BAD_ACCESS (code=1,address = 0x003f8f3)

That’s not a useful crash report. All it says is “something accessed an invalid 
memory address. At a bare minimum you should show the top few lines of the 
stack down to your application code.

I wouldn’t expect any sort of problem with a property that’s an enumerated 
type. I’ve done it often, and there are a lot of properties like that in UIKit, 
for example. But without a backtrace there’s no way of knowing why this failed.

 To answer my own question, changing the enum to an NSInteger backed NS_Enum 
 resulted in no more bad access exceptions from other chunks of code 
 attempting to change the APP_State property.

So, all you did was change the integer size of the value and the crash went 
away. This smells rather like there’s a bug lurking elsewhere in the app code 
that just happened to go away because of some slight change in the alignment of 
the value or the code being generated. If I were you I’d back out that change 
and debug what the actual crash is coming from.

—Jens
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Re: Assuring KVO compliance.

2015-04-07 Thread Alex Zavatone

On Apr 7, 2015, at 3:13 PM, Jens Alfke wrote:

 
 On Apr 7, 2015, at 7:04 AM, Alex Zavatone z...@mac.com wrote:
 
 The code that I've inherited has an enum (not an NSEnum) that represents the 
 app's connected state, 0, 1 or 2.
 
 There’s no difference. NS_ENUM is just a macro that defines a C enum, but 
 uses some newer (C99?) syntax to specify the integer size that the enum 
 should use. (Without that, if you just define a plain enum its size will be 
 sizeof(int), IIRC.)
 
 Results in this:
 Thread1: EXC_BAD_ACCESS (code=1,address = 0x003f8f3)
 
 That’s not a useful crash report. All it says is “something accessed an 
 invalid memory address. At a bare minimum you should show the top few lines 
 of the stack down to your application code.
 
 I wouldn’t expect any sort of problem with a property that’s an enumerated 
 type. I’ve done it often, and there are a lot of properties like that in 
 UIKit, for example. But without a backtrace there’s no way of knowing why 
 this failed.

Thanks.  I didn't want to flood the list with extra data, but it appears I 
should have in this case.



 To answer my own question, changing the enum to an NSInteger backed NS_Enum 
 resulted in no more bad access exceptions from other chunks of code 
 attempting to change the APP_State property.
 
 So, all you did was change the integer size of the value and the crash went 
 away. This smells rather like there’s a bug lurking elsewhere in the app code 
 that just happened to go away because of some slight change in the alignment 
 of the value or the code being generated.

Thanks.  That's what I was afraid of.  

 If I were you I’d back out that change and debug what the actual crash is 
 coming from.

With over 100 cases of @catch (NSException *exception) in this project, I think 
you're many times more right than you know.

We've got LOADS of cases of using the appDelegate as a hold-all for most 
everything and the appDelegate is referred to many times in many methods in 
many classes.

Lots of 2011 style interface and @property definition as well where the ivar is 
declared in the interface and then the @property is and then @synthesized.  

Basically, with all that's obviously out of the ordinary here, I'm looking for 
a good strategy to find the most salient path to identifying the issue here and 
refactoring/modernizing as I go along.

The first step, I guess, is recreating the exception in a fresh copy of the 
project.



Thanks much to you and Quincey.  I hope to get more on this to indicate an 
appropriate culprit and path.

Alex Zavatone
___

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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