Re: Where is my bicycle?

2015-04-07 Thread Gerriet M. Denkmann

 On 7 Apr 2015, at 00:15, Quincey Morris quinceymor...@rivergatesoftware.com 
 wrote:
 
 On Apr 6, 2015, at 09:19 , Gerriet M. Denkmann gerr...@mdenkmann.de wrote:
 
 A suggestion, though:
 
 Try building your character set using ‘characterSetWithRange:’ and/or the 
 NSMutableCharacterSet methods that add ranges, instead of using NSStrings. 
 Maybe NSCharacterSet really is UTF-32-based, but not — for code compatibility 
 reasons — when using NSStrings explicitly.

This turned out to be an excellent idea - it allowed me to create a replacement 
for characterSetWithCharactersInString: which actually works:

//  bug work-around
+ (NSCharacterSet *)gmdCharacterSetWithCharactersInString: (NSString *)string
{
if ( string.length == 0 )   //  return nil
{
NSLog(@%s string \%@\ is empty or nil → no 
CharacterSet.,__FUNCTION__, string);
return nil;
};

NSData *dat = [ string dataUsingEncoding: NSUTF32StringEncoding ];
const UTF32Char *bytes = dat.bytes;
NSUInteger length = dat.length / sizeof(UTF32Char);

NSMutableCharacterSet *mus = [ [ NSMutableCharacterSet alloc ] init ];
for( NSUInteger i = 1; i  length; i++ )//  ignore initial 
kUnicodeByteOrderMark
{
UTF32Char codePoint = bytes[i];
[ mus addCharactersInRange: NSMakeRange( codePoint, 1 ) ];
};

return mus;
}

Thanks very much for your suggestion!


Kind regards,

Gerriet.


___

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: Navigationbar doesn't work in iOS 7.1 / 8 with XCODE 6.2

2015-04-07 Thread wesley.dias wesley.dias
I've tried the two ways. Doesn't work! Well, i will keep trying!

Thank you for all!

I appreciate!

2015-04-06 17:01 GMT-03:00 Alex Zavatone z...@mac.com:

 Don't worry about your English.  It's better than my Portuguese.

 Are you trying to push a view controller onto the navigation stack, or are
 you trying to present a modal controller?

 Are you sure you want to use presentViewController?  This is the
 replacement for presenting a modal controller.

 I think you are trying to push a view controller onto the navigation
 stack.

 If that is true, then try this instead:

 [ self.navigationController pushViewController:formPedirTaxi animated:YES
 ];

 If that doesn't work, try asking on http://www.stackoverflow.com

 Good luck.
 Alex Zavatone


 On Apr 6, 2015, at 3:49 PM, wesley.dias wesley.dias wrote:

 In this point of my app i must show the navigationBar. I did the change
 that you've sent but still doesn't work. Here is the other section of my
 code:

 - (void)viewDidLoad

 {

 [ super viewDidLoad ];

 mapReference = [ [ self.navigationController viewControllers ]
 objectAtIndex:1 ];

 appDelegate = ( AppDelegate * ) [ [ UIApplication sharedApplication ]
 delegate ];

 uiCompEndereco.text = appDelegate.dataParser.pedido.endereco.endGeral;

 uiCompNumero.delegate = self;

 uiCompComplemento.delegate = self;

 uiCompReferencia.delegate = self;

 uiCompConvenio.delegate = self;

 uiCompVoucher.delegate = self;

 [ self disableVoucherFields ];

 [ uiCompBtnFormPgtoDinheiro addTarget:self 
 action:@selector(checkFormPgmto:)
 forControlEvents:UIControlEventTouchUpInside ];

 [ uiCompBtnFormPgtoCartao addTarget:self action:@selector(checkFormPgmto:)
 forControlEvents:UIControlEventTouchUpInside ];

 [ uiCompBtnFormPgtoVoucher addTarget:self 
 action:@selector(checkFormPgmto:)
 forControlEvents:UIControlEventTouchUpInside ];

 uiCompBtnAcessibilidade.backgroundColor = [ appDelegate
 colorFromHexString:@#94959a ];

 }


 - (void)viewWillAppear:(BOOL)animated

 {

 [ super viewWillAppear:animated ];

 appDelegate.dataParser.pedido.formaPagamento = 1;

 appDelegate.dataParser.pedido.acessivel = 0;

 UIBarButtonItem *btnVoltar = [ [ UIBarButtonItem alloc ] initWithTitle
 :@Voltar style:UIBarButtonItemStyleBordered target:self action:@selector(
 backToMap ) ];

 self.title = @Pedir Táxi;

 self.navigationItem.leftBarButtonItem = btnVoltar;

 self.navigationController.navigationBar.hidden = FALSE;

 // more code here
 }



 PS:

 Forgive my english, i am a brazilian and i know few words in english.

 Thank you.

 2015-04-06 16:40 GMT-03:00 Alex Zavatone z...@mac.com:

 Thanks for the image Wesley, but can you tell us what is wrong with it?
 Are we supposed to be seeing a navigation bar?

 Are you saying that the presentViewController:animated:completion: is
 covering up your view controller?

 It looks like you're asking the navigation controller to do the
 presenting of the view controller instead of asking the current view
 controller to do the presenting.

 Try removing the *.navigationController* from self.navigationController

 Try this:

 [ self presentViewController:formPedirTaxi animated:true completion:nil ];

 Not

 [ self.navigationController presentViewController:formPedirTaxi
 animated:true completion:nil ];

 I think that will work for you.  You're having the wrong object doing the
 presenting.

 Cheers,
 Alex Zavatone


 On Apr 6, 2015, at 3:32 PM, wesley.dias wesley.dias wrote:

 Okay. Here is the image:

 IMG_0010.PNG

 ​
 I am openning this with:

 [ self.navigationController presentViewController:formPedirTaxi animated:
 true completion:nil ];

 2015-04-06 16:27 GMT-03:00 Alex Zavatone z...@mac.com:

 A little more specifics will help us narrow this down.


 Updating from which version of Xcode to which version?

 Which version of iOS was this working on?  Which version of iOS are you
 using now?

 We can't see your device, so we don't know what about the navigationBar
 doesn't work.

 Is it incorrect position, the bar not displaying, UI elements don't do
 anything when tapped, what exactly?

 How are you hooking up your navigationBar?  Is it done in the storyboard
 or in code?


 I'd recommend looking at how the navigationBars are hooked up in the
 parts of your app where they do work and comparing that to how the
 navigationBars are hooked up in the parts of your app where they do not
 work.

 Good luck,
 Alex Zavatone


 On Apr 6, 2015, at 3:17 PM, wesley.dias wesley.dias wrote:

  Hi,
 
  I have an application using the native API. After update my XCODE and
 my
  test phones( 01 iPhone 4S and 01 iPhone 5 ), the navigationbar in some
  parts of my app doesn't work.
 
  Can someone help me? There is no log errors...
 
  Thanks!
 
  --
 
  Atenciosamente,
 
  Wesley C. Dias de Oliveira
 
  Desenvolvimento
 
  +55 (31) 3324-5710
 
  Avenida Luiz Paulo Franco, 603 – 3º andar – Belvedere – BH – MG – CEP:
  

Assuring KVO compliance.

2015-04-07 Thread Alex Zavatone
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/archive%40mail-archive.com

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

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: Making an array property without a backing store. How?

2015-04-07 Thread Daryle Walker
 On Apr 6, 2015, at 10:18 PM, Graham Cox graham@bigpond.com wrote:
 
 
 On 7 Apr 2015, at 12:01 pm, Daryle Walker dary...@mac.com wrote:
 
 I have an object like:
 
 @interface MyClass : NSObject
 @property (readonly) NSArray *  myDatumList;
 @property NSArray *  myDataList;
 @end
 
 The second member is meant to be an actual data member, an array of mutable 
 dictionaries. The first member isn’t supposed to have a backing store; 
 accessing a member of the first array references the corresponding member of 
 the second, then access a dictionary attribute with a custom key.
 
 I have a custom array count and array element read methods for the first 
 member.
 
 The program does nothing now. I checked with my limited debugging skills 
 that the second member has one element, but the first member is looped 
 though as if it has no elements. I see that BOTH “_myDatumList” and 
 “_myDataList” internal members exist, with the former set as NIL. I’ve heard 
 that we used to need to use the “@synthesize” command to create internal 
 members, then a later version of the Objective-C compiler did it 
 automatically. Now I have the reverse problem; the first member gets a 
 backing store automatically, but I do NOT want that; I always want to use 
 the custom array accessor methods to simulate “myDatumList” with pieces of 
 “myDataList.”
 
 So, how can I turn off auto-@synthesize? Using “@dynamic” doesn’t work; it 
 causes a crash due to a missing [MyClass myDatumList] method. I also saw a 
 random page saying that “self.myDatumList” causes this, but “myDatumList” 
 wouldn’t (like the “self.” gives the unwanted backing store have priority 
 over the array accessor methods). Is that accurate?
 
 
 
 You need to write your own getter method for myDatumList, and write the code 
 in there to do what you want it to do. Since it's a readonly property, the 
 compiler will be satisfied that you've done everything necessary to implement 
 the property and won't give it any backing store at all.
 
 As a general comment, I personally find the automatic creation of backing 
 store by default leads to bugs and confusion - how it was originally with the 
 requirement to either use @synthesise and/or write your own methods was 
 cleaner and less bug-prone, even if it did add a tiny bit of extra work. 
 C'est la vie…

I already have:

@implementation MyClass
// @synthesize myDataList = _myDataList;  // Not really needed due to 
auto-@synthesize

- (NSUInteger)countOfMyDatumList {
return self.myDataList.count;
}

- (id)objectInMyDatumListAtIndex:(NSUInteger)index {
NSDictionary * const  dict = self.myDataList[index];
return dict[@“datum”];
}
@end

Do I have to switch to a “- (NSArray *)myDatumList” method? If so, do I also 
use “@dynamic myDatumList”?

Looking at the debugger again, I noticed that my BOOL property with a custom 
getter (which simulates its result based on other member data) also has a 
“_myFlag” backing store. Is there some setting we’re missing, or do I have to 
file a bug to add no-auto-@synthesize?

…

OK, using @dynamic suppresses the creation of backing ivars, for both the BOOL 
and the NSArray. I got around the crash for the simulated array property by 
using a direct getter. So the bug is that @dynamic always looks for a direct 
getter, even for collection-based properties. (It never considers a countOf… / 
objectIn…AtIndex pair.)

Radar #20451913

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT 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: Where is my bicycle?

2015-04-07 Thread Quincey Morris
On Apr 7, 2015, at 02:21 , Gerriet M. Denkmann gerr...@mdenkmann.de wrote:
 
 it allowed me to create a replacement for characterSetWithCharactersInString: 
 which actually works

The only suggestion I have is to return ‘mus.copy’ instead of ‘mus’.

Given that we know NSCharacterSet has some optimized internal representations, 
it’s possible that NSMutableCharacterSet doesn’t use them, since there’s no 
point until you’re “finished” mutating. If you’re using a wide range of UTF-32 
values, the mutable object might be quite large, and taking a immutable copy 
might produce a very much smaller object.

Or not.



___

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: Making an array property without a backing store. How?

2015-04-07 Thread Quincey Morris
On Apr 7, 2015, at 10:58 , Daryle Walker dary...@mac.com wrote:

 @interface MyClass : NSObject
 @property (readonly) NSArray *  myDatumList;
 @property NSArray *  myDataList;
 @end
 
 @implementation MyClass
 
 - (NSUInteger)countOfMyDatumList {
return self.myDataList.count;
 }
 
 - (id)objectInMyDatumListAtIndex:(NSUInteger)index {
NSDictionary * const  dict = self.myDataList[index];
return dict[@“datum”];
 }
 @end

The problem is that this approach doesn’t actually work, not in this form. 
There’s a little bit of Doing It Wrong™, but mostly this is pretty badly broken 
in Cocoa.

Your custom accessors are *never* used, except in two circumstances:

1. If you expose them publicly, and a client of MyClass invokes them directly. 
This is fine, except that clients don’t get access via all the other NSArray 
methods for free.

2. Clients access the “myDatumList” property via a *proxy* object which is 
obtained as follows:

[someMyClassInstance valueForKey: @“myDatumList”]

Using the returned proxy object as a NSArray, they can then use any of the 
standard NSArray methods (including ordinary ‘count’, ‘objectAtIndex:’ and all 
the others) on this proxy, and the calls will be translated into some 
combination of your custom accessors.

This is fine, too, except that you’ve lost the ability for clients of the class 
to write:

myClassInstance.myDatumList.count

etc. It would *seem* you could solve this by giving MyClass a simple getter:

- (NSArray*) myDatumList {
return [self valueForKey: @“myDatumList”];
}

but if you try that, you’ll find it causes an infinite loop. *By API contract* 
(look in NSKeyValueCoding.h for the gory details), under these circumstances 
‘valueForKey’ will call the ‘myDatumList’ method — hence the loop.

(In your case, without an implementation of the “myDatumList” getter, because 
you’ve declared a “myDatumList” property and declared it @dynamic, you’d just 
end up crashing, because ‘valueForKey’ would try to call a method that doesn’t 
exist. Or, if you let it be @synthesized, ‘valueForKey’ would call a method 
that always returns nil.)

There’s no direct solution to this. You either can’t use the custom NSArray 
accessors, or clients of the class have to remember to us the crummy 
‘valueForKey’ approach and you have to get rid of the “myDatumList” property. 
The indirect solution is to implement your own proxy object. It’s doable, and 
I’ve done it in the past, but it makes your head hurt.

My suggestion, therefore, is to take one of the following approaches:

— If clients of the class access “myDatumList” in limited ways, just expose the 
custom accessors directly, and don’t have the @property at all.

— Have the “myDataList” property be cleverer, and let it maintain a parallel 
array (_myDatumList). This is just an array, therefore, without custom 
accessors, so the “myDatumList” property will work fine.

Finally, if on top of all of this you want the “myDatumList” property to be KVO 
compliant — if you want to KVO observe it — there’s yet another level of 
complication because there’s a different proxy involved:

[self-or-someMyClassInstance  mutableArrayValueForKey: @“myDatumList”]

and/or you must provide KVO compliance manually when updating the backing store 
NSArrays. (And if you think this proxy avoids the looping problem of the 
non-mutable proxy — it doesn’t.)

Sorry to ruin your day. :)



___

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: Where is my bicycle?

2015-04-07 Thread Charles Srstka
On Apr 7, 2015, at 2:24 PM, Jens Alfke j...@mooseyard.com wrote:
 
 This is the same process that allows you to put Japanese or Cyrillic 
 characters in a string and render them in Helvetica or Papyrus even though 
 those fonts don’t support those character sets.

I really want to see a Cyrillic version of Papyrus now. ;-)

Charles

___

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: Where is my bicycle?

2015-04-07 Thread Jens Alfke

 On Apr 7, 2015, at 12:59 PM, Charles Srstka cocoa...@charlessoft.com wrote:
 
 I really want to see a Cyrillic version of Papyrus now. ;-)

http://ihateyouare.deviantart.com/art/Papyrus-Plain-Cyrillic-165111766 
http://ihateyouare.deviantart.com/art/Papyrus-Plain-Cyrillic-165111766

You’re welcome :)

—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

Re: Making an array property without a backing store. How?

2015-04-07 Thread Charles Srstka
On Apr 7, 2015, at 2:33 PM, Jens Alfke j...@mooseyard.com wrote:
 
 What Quincey said. I banged my head against this a lot back in 2005 or so and 
 gave up on this approach. It sounds lovely — I can expose this property as an 
 NSArray in my class’s public API even though it’s not really implemented as 
 an NSArray! — but it just doesn’t work, not unless you make all of your’ 
 class’s clients use
   [myInstance valueForKey: @“myDatumList”]
 instead of
   myInstance.myDatumList
 Yuck.
 
 I first tried to work around this by wrapping that in a property:
   - (NSArray*) myDatumList {
   return [self valueForKey: @“myDatumList”];
   }
 As you might guess, this causes an infinite regress and crashes. :(
 
 Then I tried to get clever and give the public property a different name from 
 the one with the -countOf and …atIndex methods:
   - (NSArray*) myPublicDatumList {
   return [self valueForKey: @“myDatumList”];
   }
 The problem with this is that the .myPublicDatumList property isn’t 
 KV-observable since the actual changes are happening to myDatumList instead. 
 But if you don’t need the property to be mutable, this might be good enough 
 for you…

Does this not work?

+ (NSSet *)keyPathsForValuesAffectingValueForMyPublicDatumList {
return [NSSet setWithObject:@“myDatumList”];
}

Charles

___

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: addTarget: forControlEvents: ?

2015-04-07 Thread Kyle Sluder

On Tue, Apr 7, 2015, at 02:49 PM, Dave wrote:
 Hi All,
 
 Given the iOS/Cocoa-Touch code:
 
 [self addTarget:self action:@selector(buttonTouchUpInsideAction:)
 forControlEvents:UIControlEventTouchUpInside];
 [self addTarget:self action:@selector(buttonTouchDownAction:)
 forControlEvents:UIControlEventTouchDownInside];
 
 What is the Equivalent for Mac/Cocoa?

The Mac does not support multiple targets for a single control.

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

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

Re: Making an array property without a backing store. How?

2015-04-07 Thread Jens Alfke

 On Apr 7, 2015, at 11:55 AM, Quincey Morris 
 quinceymor...@rivergatesoftware.com wrote:
 
 The problem is that this approach doesn’t actually work, not in this form. 
 There’s a little bit of Doing It Wrong™, but mostly this is pretty badly 
 broken in Cocoa.

What Quincey said. I banged my head against this a lot back in 2005 or so and 
gave up on this approach. It sounds lovely — I can expose this property as an 
NSArray in my class’s public API even though it’s not really implemented as an 
NSArray! — but it just doesn’t work, not unless you make all of your’ class’s 
clients use
[myInstance valueForKey: @“myDatumList”]
instead of
myInstance.myDatumList
Yuck.

I first tried to work around this by wrapping that in a property:
- (NSArray*) myDatumList {
return [self valueForKey: @“myDatumList”];
}
As you might guess, this causes an infinite regress and crashes. :(

Then I tried to get clever and give the public property a different name from 
the one with the -countOf and …atIndex methods:
- (NSArray*) myPublicDatumList {
return [self valueForKey: @“myDatumList”];
}
The problem with this is that the .myPublicDatumList property isn’t 
KV-observable since the actual changes are happening to myDatumList instead. 
But if you don’t need the property to be mutable, this might be good enough for 
you…

—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: Where is my bicycle?

2015-04-07 Thread Jens Alfke

 On Apr 6, 2015, at 2:09 PM, Jack Brindle jackbrin...@me.com wrote:
 
 Have you checked the Font you are using to display the character string to 
 see if it contains the bicycle character? If not, you probably won’t get the 
 character you seek.

Fonts have nothing to do with it; they’re an aspect of rendering text, not of 
working with the text in memory. (If it weren’t this way, you wouldn’t be able 
to work with NSString at all; everything would have to be based on 
NSAttributedString to carry around the font info for every character.)

The bicycle is a well-defined Unicode character, an emoji. When it comes time 
to render it, the typesetter will look for a glyph in the current font for that 
character code. It probably won’t find one, so it will go through a series of 
fallback fonts looking for a glyph until it finds one in whatever internal font 
stores the emoji glyphs. Then it uses that font to render it.

This is the same process that allows you to put Japanese or Cyrillic characters 
in a string and render them in Helvetica or Papyrus even though those fonts 
don’t support those character sets. They’re actually being rendered in whatever 
system font is the default for those character sets. This is all invisible to 
you unless you start diving down into the NSTypesetter or CoreText APIs.

—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

addTarget: forControlEvents: ?

2015-04-07 Thread Dave
Hi All,

Given the iOS/Cocoa-Touch code:

[self addTarget:self action:@selector(buttonTouchUpInsideAction:) 
forControlEvents:UIControlEventTouchUpInside];
[self addTarget:self action:@selector(buttonTouchDownAction:) 
forControlEvents:UIControlEventTouchDownInside];

What is the Equivalent for Mac/Cocoa?

Thanks a lot
Cheers
Dave


___

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: Making an array property without a backing store. How?

2015-04-07 Thread Greg Parker

 On Apr 6, 2015, at 7:01 PM, Daryle Walker dary...@mac.com wrote:
 
 I have an object like:
 
 @interface MyClass : NSObject
 @property (readonly) NSArray *  myDatumList;
 @property NSArray *  myDataList;
 @end
 
 The second member is meant to be an actual data member, an array of mutable 
 dictionaries. The first member isn’t supposed to have a backing store; 
 accessing a member of the first array references the corresponding member of 
 the second, then access a dictionary attribute with a custom key.
 
 I have a custom array count and array element read methods for the first 
 member.
 
 The program does nothing now. I checked with my limited debugging skills that 
 the second member has one element, but the first member is looped though as 
 if it has no elements. I see that BOTH “_myDatumList” and “_myDataList” 
 internal members exist, with the former set as NIL. I’ve heard that we used 
 to need to use the “@synthesize” command to create internal members, then a 
 later version of the Objective-C compiler did it automatically. Now I have 
 the reverse problem; the first member gets a backing store automatically, but 
 I do NOT want that; I always want to use the custom array accessor methods to 
 simulate “myDatumList” with pieces of “myDataList.”
 
 So, how can I turn off auto-@synthesize? Using “@dynamic” doesn’t work; it 
 causes a crash due to a missing [MyClass myDatumList] method.

@dynamic turns off automatic property synthesis. The compiler will not create 
ivar storage nor accessor methods for an @dynamic property. 

Did you implement the method -[MyClass myDatumList] ? If you don't synthesize 
the property then you need to write its accessor methods yourself.


 I also saw a random page saying that “self.myDatumList” causes this, but 
 “myDatumList” wouldn’t (like the “self.” gives the unwanted backing store 
 have priority over the array accessor methods). Is that accurate?

`self.property` reads or writes the property via its accessor methods. `ivar` 
or `self-ivar` accesses an instance variable's storage directly, bypassing any 
property accessor methods (synthesized or not) that use that storage. If you 
have a property and an ivar with the same name then `self.property` and 
`property` will both be legal and will behave differently. 


-- 
Greg Parker gpar...@apple.com Runtime Wrangler



___

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: Making an array property without a backing store. How?

2015-04-07 Thread Graham Cox

 On 8 Apr 2015, at 3:58 am, Daryle Walker dary...@mac.com wrote:
 
 Looking at the debugger again, I noticed that my BOOL property with a custom 
 getter (which simulates its result based on other member data) also has a 
 “_myFlag” backing store. Is there some setting we’re missing, or do I have to 
 file a bug to add no-auto-@synthesize?
 


Others have given you a much more complete answer than I did about 
-myDatumList, but just to pick up on this one.

I assume you've declared this something like:

@property (assign) BOOL  myFlag;

But then implemented it something like:

- (BOOL)  myFlag
{
return someOtherMemberData.flag;
}


Without any @synthesize for it.

The problem here is that the property is declared (assign). That means it's 
something that requires both a getter and a setter. So it has auto-synthesized 
the setter, as you only supplied the getter. In auto-synthesizing the setter, 
it has to provide backing store for it, hence _myFlag.

To fix that, you have a couple of options depending on what you need.

First, you could declare the property readonly. Then, the compiler knows no 
setter is required and won't synthesize one, and won't create backing store.

The other is to write the setter method as well. It could either set the 
indirect property, or just do nothing (though in the latter case that would be 
a readonly property, so you'd be better off declaring it as such).



As I mentioned, I feel that auto-synthesizing generally is somewhat evil. It 
adds code that you can't see and can't easily debug, and adds ivars that you 
can't see which may be masking (or masked by) other ivars that you might assume 
are the ones in use (if you forgot a corresponding @synthesize, which is an 
easy error to make since auto-synthesize covers it up). Since you can't turn 
off auto synthesizing, the next best thing is at least to enable the warning 
that it's done it: CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS, shown as 
Implicit Synthesized Properties in the build settings.

Code that isn't magic is more readable, so for me declaring explicit ivars, 
writing getters, setters or @synthesize statements is always better than 
leaving it to invisible compiler magic, even if it adds a little more work. 
That small amount of extra work is easily repaid in time saved debugging an 
auto-synthesized ivar that you didn't even know was there. It has happened to 
me so many times now that I can usually find the problem quickly because I can 
smell the symptoms, but I feel for newbies to this stuff who have been misled 
into writing hard-to-debug code by something that really saves almost nothing 
in coding effort. 

@property was a great improvement to Obj-C, but auto-synthesizing them was not. 
One of Apple's less useful design decisions, IMHO.

--Graham



___

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