Re: CFPreferences and init.
Re: CFPreferences and init.
- Subject: Re: CFPreferences and init.
- From: "Kyle Sluder" <email@hidden>
- Date: Sun, 26 Oct 2008 17:40:59 -0400
On Sun, Oct 26, 2008 at 4:12 PM, Adam Penny <email@hidden> wrote:
> This is my code for the method in question and it's used for the NSTableView
> bindings:
Your code is rather disorganized. Particularly, your use of else
clauses is confusing and prone to introducing logic errors.
> - (void) setServers:(NSMutableArray *)a;
The Objective-C parser will allow you to have a semicolon at the end
of a method implementation declaration spec. Don't do it, it's
confusing. I'm also pretty sure that this behavior isn't documented
anywhere.
Also, you should be asking for an NSArray, not an NSMutableArray. By
asking for an NSMutableArray, you are implicitly telling the caller
that they may change the contents of the array from underneath you at
any time. In a to-many relationship like this, it is almost
guaranteed that this behavior is not what you want.
> {
> //Method for adding a new server, with mac address to the servers
> array
> if (a==servers) return;
You don't want to do this. What are the odds that the NSArray object
your caller is providing is the exact same instance as the one you
already have? Just leave the condition out; it will never execute in
practice anyway.
> [a retain];
> [servers release];
> servers = a;
Instead of just assigning a to your ivar, use [a copy]. This goes in
hand with the recommendation about the argument type above. You
probably don't want to store an NSMutableArray, and if the caller has
provided you an NSMutableArray, which is fine since the method just
asks for an NSArray, you don't want the caller to mutate the
collection your object is supposed to be tracking. If you really,
*really* need your ivar to be mutable, use -mutableCopy instead of
-copy.
> NSArray *serversToCopy = [servers copy];
This line is obsoleted if you follow my recommendation above.
> //Next line causes an exception when adding a row.
> if ([servers count]!=0) CFPreferencesSetAppValue(CFSTR("servers"),
> (NSArray *)serversToCopy, appID);
> else CFPreferencesSetAppValue(CFSTR("servers"), NULL, appID);
> else NSLog(@"It's zero!");
I don't know how this code can compile; that second else clause
doesn't match up with any if statement. Is one of them commented out
in your code?
Where is appID coming from? Is it a constant NSString somewhere, like
it should be?
So here's how I'd rewrite your method (warning, code written in the
compose window, YMMV):
/***** MyClass.h *****/
extern NSString *appID;
extern NSString *serversPlistKey;
@interface MyClass
{
NSArray *servers;
}
-(void)setServers:(NSArray *)newServers;
@end
/***** MyClass.m *****/
NSString *appID = @"uk.co.pennynet.Wopol";
NSString *serversPlistKey = @"servers";
@implementation MyClass
-(id)init
{
if(self = [super init])
{
// ... other init code ...
servers = [[NSArray alloc] init];
// ... more init code ...
}
return self;
}
-(void)setServers:(NSArray *)newServers
{
servers = [[newServers copy] retain];
if([servers count] > 0)
CFPreferencesSetAppValue((CFStringRef)serversPlistKey,
(CFArrayRef)servers,
(CFStringRef)appID);
else
CFPreferencesSetAppValue((CFStringRef)serversPlistKey,
NULL, (CFStringRef)appID);
[self updatePrefs];
}
-(void)dealloc
{
// ... other dealloc code ...
[servers release];
// ... more dealloc code ...
[super dealloc];
}
@end
> The other thing that's confusing me is that what was an XML Plist that I did
> by hand like this:
[...snip...]
> has been transformed by the synchronization to this(!):
That's the binary plist representation. This will be transparent to
well-behaved applications. Naughty ones will try to read the raw XML
plist representation and fail, but ones that use the plist
serialization API won't know the difference.
HTH,
--Kyle Sluder
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden