problem with applying md5 to data

2011-06-29 Thread Wilker
Hi guys,

I need to generate a hash from a file, the hash algorithm is here:
http://thesubdb.com/api/

I'm trying to implement it on Objective-C but I'm having really trouble on
it...

This is my current implementation:

//
//  SMSubdbSource.m
//  Subtitle Master
//
//  Created by Wilker Lúcio da Silva on 6/23/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import SMSubdbSource.h
#import CommonCrypto/CommonDigest.h

@implementation SMSubdbSource

+(NSString *)md5:(NSString *)str {
const char *cStr = [str UTF8String];
unsigned char result[16];
CC_MD5(cStr, (unsigned int) strlen(cStr), result);
return [NSString stringWithFormat:

@%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X,
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}

+(NSString *)generateHashFromPath:(NSString *)path {
const NSUInteger CHUNK_SIZE = 65536;

NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];

if (file == nil) return nil;

unsigned long fileSize = [[[NSFileManager defaultManager]
attributesOfItemAtPath:path error:nil] fileSize];

NSMutableData *fileData = [[NSMutableData alloc]
initWithCapacity:CHUNK_SIZE * 2];

[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
[file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];

[file closeFile];

NSString *dataString = [[NSString alloc] initWithData:fileData
encoding:NSASCIIStringEncoding];

return [[SMSubdbSource md5:dataString] lowercaseString];
}

@end

It works well if file only contains ASCII simple chars, but the real files
(that contains video binary data) generates wrong hash... I mean the problem
should be when trying to generate the string and MD5 digest from it...

How I can make it work correctly?

---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600
___

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


NSDocument new file logic

2011-06-29 Thread Martin Hewitson
Dear list,

I have an NSPersistentDocument subclass which encapsulates a project for the 
user. When the user creates a new project, they specify a name and a location 
on disk. I then want to create a new instance of my NSDocument subclass as if 
it was saved exactly where the user wants it to be. I want to do this because 
the app then creates additional files (which are managed by the project -- 
think Xcode) which are placed in the same location as the project file. 

In the past I achieved this in a somewhat unsatisfactory way by just calling 
newDocument: then saveDocument: and getting the user to immediately save the 
document before the app does the rest of the setup steps. This was working, but 
it does mean that the user is immediately presented with a save panel, which is 
not so nice. I'd rather present a custom panel telling them to enter a project 
name and a location on disk. Anyway, that aside, this scheme doesn't seem 
robust to future OS implementations (maybe the saveDocument: behaviour changes, 
for example).  What I'd really like is an NSDocumentController method like

-(id)createDocumentAtURL:(NSURL*)aURL ofType:(NSString*)type 
error:(NSError**)anError;

but that doesn't seem to exist. 

Can anyone recommend a way to do what I want? In other words, to 
programmatically create an NSDocument instance already saved on disk? This 
behaviour is essentially what Xcode is doing when one creates a new project.

Best wishes,

Martin


Martin Hewitson
Albert-Einstein-Institut
Max-Planck-Institut fuer 
Gravitationsphysik und Universitaet Hannover
Callinstr. 38, 30167 Hannover, Germany
Tel: +49-511-762-17121, Fax: +49-511-762-5861
E-Mail: martin.hewit...@aei.mpg.de
WWW: http://www.aei.mpg.de/~hewitson






___

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: problem with applying md5 to data

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 00:02, Wilker wrote:

 I'm trying to implement it on Objective-C but I'm having really trouble on
 it...

There are many things wrong with your implementation.

 +(NSString *)generateHashFromPath:(NSString *)path {
const NSUInteger CHUNK_SIZE = 65536;
 
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
 
if (file == nil) return nil;
 
unsigned long fileSize = [[[NSFileManager defaultManager]
 attributesOfItemAtPath:path error:nil] fileSize];
 
NSMutableData *fileData = [[NSMutableData alloc]
 initWithCapacity:CHUNK_SIZE * 2];
 
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
[file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 
[file closeFile];

This is not the worst way to read the entire contents of a file into a NSData 
object, but it's pretty bad. :)

It would be far easier and more efficient to use [NSData 
dataWithContentsOfFile: path options: NSDataReadingMapped | 
NSDataReadingUncached error: NULL];

NSString *dataString = [[NSString alloc] initWithData:fileData
 encoding:NSASCIIStringEncoding];

You say the file contains binary data. Running it through the ASCII string 
encoding is going to throw away every character that isn't ASCII (i.e. it will 
throw away every character with its high order bit set). That isn't what you 
want.

Also, converting a large NSData object to a NSString via any encoding is going 
to be horrendously expensive (in CPU and memory cost). That isn't what you want.

return [[SMSubdbSource md5:dataString] lowercaseString];
 }

 +(NSString *)md5:(NSString *)str {
const char *cStr = [str UTF8String];

Since you're passing in a (NSString) string of ASCII characters, you're going 
to get out a (C) string of exactly the same ASCII characters, since ASCII 
characters are represented by themselves in UTF8. This isn't what you want.

unsigned char result[16];
CC_MD5(cStr, (unsigned int) strlen(cStr), result);
return [NSString stringWithFormat:
 
 @%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X,
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
 }

If you're trying to compute the digest of the binary data, you can compute it 
directly from the NSData object like this:

CC_MD5 (fileData.bytes, fileData.length, result);


___

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: problem with applying md5 to data

2011-06-29 Thread Wilker
Thanks for the answer Quincey,

I did resolved just before you post here :)

Used this (now in separated files):

+(NSString *)md5HexDigestFromChar:(const void *)str
withLength:(CC_LONG)lenght {
unsigned char result[CC_MD5_DIGEST_LENGTH];

CC_MD5(str, lenght, result);

NSMutableString *ret = [NSMutableString
stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

for (int i = 0; i  CC_MD5_DIGEST_LENGTH; i++) {
[ret appendFormat:@%02x, result[i]];
}

return [ret lowercaseString];
}

+(NSString *)generateHashFromPath:(NSString *)path {
const NSUInteger CHUNK_SIZE = 65536;

NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];

if (file == nil) return nil;

unsigned long fileSize = [[[NSFileManager defaultManager]
attributesOfItemAtPath:path error:nil] fileSize];

NSMutableData *fileData = [[NSMutableData alloc]
initWithCapacity:CHUNK_SIZE * 2];

[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
[file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];

[file closeFile];

return [SMEncodingUtilities md5HexDigestFromChar:[fileData bytes]
withLength:(unsigned int)[fileData length]];
}

You said the way I readed the file is bad... But I don't need to read the
entire file, just 64kb of first, and 64kb of last, are you sure that will be
better to read it entirely?

Thanks for the support :)
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 4:27 AM, Quincey Morris quinceymor...@earthlink.net
 wrote:

 On Jun 29, 2011, at 00:02, Wilker wrote:

  I'm trying to implement it on Objective-C but I'm having really trouble
 on
  it...

 There are many things wrong with your implementation.

  +(NSString *)generateHashFromPath:(NSString *)path {
 const NSUInteger CHUNK_SIZE = 65536;
 
 NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
 
 if (file == nil) return nil;
 
 unsigned long fileSize = [[[NSFileManager defaultManager]
  attributesOfItemAtPath:path error:nil] fileSize];
 
 NSMutableData *fileData = [[NSMutableData alloc]
  initWithCapacity:CHUNK_SIZE * 2];
 
 [fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 [file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
 [fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 
 [file closeFile];

 This is not the worst way to read the entire contents of a file into a
 NSData object, but it's pretty bad. :)

 It would be far easier and more efficient to use [NSData
 dataWithContentsOfFile: path options: NSDataReadingMapped |
 NSDataReadingUncached error: NULL];

 NSString *dataString = [[NSString alloc] initWithData:fileData
  encoding:NSASCIIStringEncoding];

 You say the file contains binary data. Running it through the ASCII string
 encoding is going to throw away every character that isn't ASCII (i.e. it
 will throw away every character with its high order bit set). That isn't
 what you want.

 Also, converting a large NSData object to a NSString via any encoding is
 going to be horrendously expensive (in CPU and memory cost). That isn't what
 you want.

 return [[SMSubdbSource md5:dataString] lowercaseString];
  }

  +(NSString *)md5:(NSString *)str {
 const char *cStr = [str UTF8String];

 Since you're passing in a (NSString) string of ASCII characters, you're
 going to get out a (C) string of exactly the same ASCII characters, since
 ASCII characters are represented by themselves in UTF8. This isn't what you
 want.

 unsigned char result[16];
 CC_MD5(cStr, (unsigned int) strlen(cStr), result);
 return [NSString stringWithFormat:
 
  @%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X,
 result[0], result[1], result[2], result[3],
 result[4], result[5], result[6], result[7],
 result[8], result[9], result[10], result[11],
 result[12], result[13], result[14], result[15]
 ];
  }

 If you're trying to compute the digest of the binary data, you can compute
 it directly from the NSData object like this:

CC_MD5 (fileData.bytes, fileData.length, result);



___

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: NSDocument new file logic

2011-06-29 Thread Quincey Morris
On Jun 28, 2011, at 23:58, Martin Hewitson wrote:

 In the past I achieved this in a somewhat unsatisfactory way by just calling 
 newDocument: then saveDocument: and getting the user to immediately save the 
 document before the app does the rest of the setup steps.

Using the action methods (newDocument: and saveDocument:) is what makes your 
approach unappealing for the user. In Snow Leopard or earlier, for a regular 
document, the steps are something like this:

1. Get the project name and file system location. (You can use the Save panel 
for this, but you put it up yourself rather than having 'newDocument:' do it. 
Or, you can use some kind of custom dialog.)

2. Create a document file at that location. (Typically, you create a default 
data model or import some data, turn it into a keyed archive, write the archive 
data to a file.)

3. Use NSDocumentController's 'openDocumentWithContentsOfURL:display:error:' 
method to open the now-existing document normally.

You can use much the same approach for NSPersistentDocument, but step 2 is a 
little different. Here's a method I wrote (based on some sample code somewhere 
in the Core Data documentation, but I don't remember where) that creates a new 
store. It returns a managed object context because you probably want to put 
something in the store (and 'save:' it) before re-opening it as a 
NSPersistentDocument in step 3.

 + (NSManagedObjectContext*) managedObjectContextForStoreURL: (NSURL*) storeURL
 {
   //  Find the document's model
   
   NSManagedObjectModel* model = [NSManagedObjectModel 
 mergedModelFromBundles: nil];
   if (!model)
   return nil;
   
   //  Create a persistent store
   
   NSPersistentStoreCoordinator* psc = [[NSPersistentStoreCoordinator 
 alloc] initWithManagedObjectModel: model];
   if (!psc)
   return nil;
   
   NSError* error;
   NSPersistentStore* store = [psc addPersistentStoreWithType: 
 NSSQLiteStoreType
   
  configuration: nil 
   
URL: storeURL 
   
options: nil 
   
  error: error];
   if (!store)
   return nil;
   
   //  Create a managed object context for the store
   
   NSManagedObjectContext* managedContext = [[NSManagedObjectContext 
 alloc] init];
   if (!managedContext)
   return nil;
   
   managedContext.persistentStoreCoordinator = psc;
   managedContext.undoManager = nil;
   
   return managedContext;
 }

HTH


___

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: problem with applying md5 to data

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 00:27, Quincey Morris wrote:

   [fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
   [file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
   [fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 
   [file closeFile];
 
 This is not the worst way to read the entire contents of a file into a NSData 
 object, but it's pretty bad. :)
 
 It would be far easier and more efficient to use [NSData 
 dataWithContentsOfFile: path options: NSDataReadingMapped | 
 NSDataReadingUncached error: NULL];

Er, two things.

I didn't notice until after I posted that you weren't reading the whole file. 
So, sorry, pretty bad was too strong -- I'm upgrading my response to not the 
best. :)

I think the way I suggested is still the best way, because (typically) using 
the NSDataReadingMapped means the file contents are mapped into virtual memory, 
so pages (4KB, or whatever the VM page size is) are not actually read until you 
try to access them.

If you use CC_MD5_Init/Update (first part)/Update (last part)/Final instead of 
the convenience method that does it all, only the parts of the file you need 
will actually be read.

NSDataReadingMapped is in general the most efficient way to read a file when 
you only need to read any part once, I think.

The problem with NSFileHandle is that it pretty much sucks as a class. It 
doesn't return any errors, so if something goes wrong it's either going to 
throw an exception or just ignore it. IIRC it has no API contract regarding 
error reporting.

Second thing... 

I forgot to point out that your code has a glaring bug. With your declarations, 
'fileSize - CHUNK_SIZE' in 'MAX(0, fileSize - CHUNK_SIZE)' is an unsigned 
expression. It can't go negative, and so that statement isn't doing what it 
looks like it's doing.

One more thing ...

Since you have no release/retain calls, I'm assuming you're using garbage 
collection. If that's the case, then this line is very, very dangerous:

 return [SMEncodingUtilities md5HexDigestFromChar:[fileData bytes] 
 withLength:(unsigned int)[fileData length]];

You're passing an *interior* pointer to fileData's private storage, but the 
(compiler-optimized) lifetime of 'fileData' ends *before* the md5 method is 
entered, and so the object is subject to being collected *before* you've used 
the pointer. This will crash.

In your code, the window of danger is pretty small. But it will crash 
eventually.

The solution is to put a reference to the object after the call:

 NSString* result = [SMEncodingUtilities md5HexDigestFromChar:[fileData 
 bytes] withLength:(unsigned int)[fileData length]];
 [fileData self];
 return result;

It's a PITA, but you gotta be careful with NSData.

___

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: NSDocument new file logic

2011-06-29 Thread Martin Hewitson
Wonderful! Thanks very much. I will give this a try. Writing out the core data 
store was the bit I was missing.

Martin


On Jun 29, 2011, at 9:54 AM, Quincey Morris wrote:

 On Jun 28, 2011, at 23:58, Martin Hewitson wrote:
 
 In the past I achieved this in a somewhat unsatisfactory way by just calling 
 newDocument: then saveDocument: and getting the user to immediately save the 
 document before the app does the rest of the setup steps.
 
 Using the action methods (newDocument: and saveDocument:) is what makes your 
 approach unappealing for the user. In Snow Leopard or earlier, for a regular 
 document, the steps are something like this:
 
 1. Get the project name and file system location. (You can use the Save panel 
 for this, but you put it up yourself rather than having 'newDocument:' do it. 
 Or, you can use some kind of custom dialog.)
 
 2. Create a document file at that location. (Typically, you create a default 
 data model or import some data, turn it into a keyed archive, write the 
 archive data to a file.)
 
 3. Use NSDocumentController's 'openDocumentWithContentsOfURL:display:error:' 
 method to open the now-existing document normally.
 
 You can use much the same approach for NSPersistentDocument, but step 2 is a 
 little different. Here's a method I wrote (based on some sample code 
 somewhere in the Core Data documentation, but I don't remember where) that 
 creates a new store. It returns a managed object context because you probably 
 want to put something in the store (and 'save:' it) before re-opening it as a 
 NSPersistentDocument in step 3.
 
 + (NSManagedObjectContext*) managedObjectContextForStoreURL: (NSURL*) 
 storeURL
 {
  //  Find the document's model
  
  NSManagedObjectModel* model = [NSManagedObjectModel 
 mergedModelFromBundles: nil];
  if (!model)
  return nil;
  
  //  Create a persistent store
  
  NSPersistentStoreCoordinator* psc = [[NSPersistentStoreCoordinator 
 alloc] initWithManagedObjectModel: model];
  if (!psc)
  return nil;
  
  NSError* error;
  NSPersistentStore* store = [psc addPersistentStoreWithType: 
 NSSQLiteStoreType
  
  configuration: nil 
  
URL: storeURL 
  
options: nil 
  
  error: error];
  if (!store)
  return nil;
  
  //  Create a managed object context for the store
  
  NSManagedObjectContext* managedContext = [[NSManagedObjectContext 
 alloc] init];
  if (!managedContext)
  return nil;
  
  managedContext.persistentStoreCoordinator = psc;
  managedContext.undoManager = nil;
  
  return managedContext;
 }
 
 HTH
 
 


Martin Hewitson
Albert-Einstein-Institut
Max-Planck-Institut fuer 
Gravitationsphysik und Universitaet Hannover
Callinstr. 38, 30167 Hannover, Germany
Tel: +49-511-762-17121, Fax: +49-511-762-5861
E-Mail: martin.hewit...@aei.mpg.de
WWW: http://www.aei.mpg.de/~hewitson






___

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: dispatch_async Performance Issues

2011-06-29 Thread Andreas Grosam
Hi Jonathan,

I'm happy that your guesses exactly match the results of my investigations. :)

Actually, the compiler (LLVM here) is doing an amazing job when optimizing. 
Although I'm happy with this, it makes such tests a pain, since often enough 
the compiler simply strips the code away what I wanted to test :)

So again, I modified the test code in order to prevent the undesired effects of 
such optimizations. So, I actually *use* the future in the test code, so that 
the compiler does not strip away dereferencing and does not strip away 
calculating the sum in the inner loops.

After this modifications, more hints to performance issues became apparent ...

The cause is definitely the way the C++ compiler handles and generates code for 
possibly C++ exceptions. Accidentally, my Iterator had a non trivial destructor 
(or more precisely, the buffer class which is a member of the Iterator), namely 
it releases a CFData object. Due to this, the compiler had to generate some 
extra code which causes the performance difference.

After fixing the buffers list class and the iterator class, the test performs 
as expected. With C++ Exceptions enabled, USE_FUTURE defined, and all code 
fixed so that it actually uses the Future, the test runs as follows:

 CFDataBuffers Benchmark 
Using  Future: Yes
Data size: 131072KB, Buffer size: 8192, N = 16384, C = 2


[Classic]: Elapsed time: 473.539ms  
(Single threaded, naive implementation using a NSMutableData object constructed 
by appending many NSData buffers)

[ConcurrentProduceConsume1]: Elapsed time: 135.162ms   
(GCD, straight and forward implementation, using pointers)

[ConcurrentProduceConsumeIter]: Elapsed time: 363.226ms
(GCD, old and unmodified code, using C++ Iterator concept)

[ConcurrentProduceConsumeIter2]: Elapsed time: 189.002ms 
(Fixed Iterator and fixed buffers list)


As usual, take the numbers with a grain of salt. The workload of the consumer 
is minimal, and producing the buffers doesn't block as it would likely happen 
when downloading data.



When dealing with small amount of data (25KByte) the GCD approach does not 
perform better. In this scenario, the classic approach would be faster:

Data size: 24KB, Buffer size: 8192, N = 3, C = 2
[Classic]: Elapsed time: 0.0543303ms
[ConcurrentProduceConsumeIter2]: Elapsed time: 0.116253ms



Regards, and thank you again for you help!
Andreas



On Jun 28, 2011, at 9:37 PM, Jonathan Taylor wrote:

 In the meantime however, I found one (surprising) cause of the performance 
 issue. After making the versions  *more* equivalent the issue become 
 apparent.  I restructured the second version (using the C++ iterators) and 
 will discuss this in more detail. The culprit is in the consumer part as 
 follows:
 
 New restructured code:
 
 [...]
 
 The difference compared to the former code provided in the previous mail is 
 now
 
 1) The C++ instances, that is the iterators, are defined locally within the 
 block.
 
 2) The Future (that is the result of the operation) is conditional 
 compiled in or out, in order to test its impact.
Here, the __block modifier is used for the Future variables sum and 
 total.  
When using pointers within the block accessing the outside variables, the 
 performance does not differ, but using __block may be more correct.
 
 
 Ah - now then! I will take a very strong guess as to what is happening there 
 (I've done it myself, and seen it done by plenty of others! [*]). In the case 
 where you do NOT define USE_FUTURE, your consumer thread as written in your 
 email does not make any use of the variables sum_ and total_. Hence the 
 compiler is entirely justified in optimizing out those variables entirely! It 
 will still have to check the iterator against eof, and may have to 
 dereference the iterator[**], but it does not need to update the sum_ or 
 total_ variables. 
 
 It may well be that there is still a deeper performance issue with your 
 original code, and I'm happy to have another look at that when I have a 
 chance. I suggest you deal with this issue first, though, as it appears to be 
 introducing misleading discrepancies in the execution times you're using for 
 comparison.
 
 As I say, it's quite a common issue when you start stripping down code with 
 the aim of doing minimal performance comparisons. The easiest solution is 
 either to printf the results at the end (which forces the compiler to 
 actually evaluate them!), or alternatively do the sort of thing you're doing 
 when USE_FUTURE is defined - writing to a shadow variable at the end. If you 
 declare your shadow variable as volatile then the compiler is forced to 
 write the result and is not permitted to optimize everything out.
 
 Hope that helps, even if it may not deal with your original problem yet. 
 Apologies that my first round of guesses were wrong - I'm pretty sure about 
 this one though :)
 
 Jonny
 
 
 [**] Completely unrelated to this thread, but see this rather extreme 

Fuzzy string matching

2011-06-29 Thread Eric E. Dolecki
Hey all,

I have an application (iOS) that is doing speech to text. The
resulting string I'd like to fuzzy match against the user's onboard
music library, and play a song, album, genre, etc. as appropriate. I
am looking for a really good fuzzy string matching engine. I found
this: http://www.locayta.com/, not sure it's something I could use or
not. Also I found this code (but it's not quote accurate enough for
reliable results):

Any better ideas for a better fuzzy string match?

// Return the minimum of a, b and c - used by compareString:withString:
-(NSInteger)smallestOf:(NSInteger)a andOf:(NSInteger)b andOf:(NSInteger)c
{
NSInteger min = a;
if ( b  min )
min = b;

if( c  min )
min = c;

return min;
}

-(NSInteger)smallestOf:(NSInteger)a andOf:(NSInteger)b
{
NSInteger min=a;
if (b  min)
min=b;

return min;
}

-(float)compareString:(NSString *)originalString withString:(NSString
*)comparisonString
{
// Normalize strings
[originalString stringByTrimmingCharactersInSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet]];
[comparisonString stringByTrimmingCharactersInSet:[NSCharacterSet
whitespaceAndNewlineCharacterSet]];

originalString = [originalString lowercaseString];
comparisonString = [comparisonString lowercaseString];

// Step 1 (Steps follow description at 
http://www.merriampark.com/ld.htm)
NSInteger k, i, j, cost, * d;
float distance;
NSInteger n = [originalString length];
NSInteger m = [comparisonString length];

if( n++ != 0  m++ != 0 ) {

d = malloc( sizeof(NSInteger) * m * n );

// Step 2
for( k = 0; k  n; k++)
d[k] = k;

for( k = 0; k  m; k++)
d[ k * n ] = k;

// Step 3 and 4
for( i = 1; i  n; i++ )
for( j = 1; j  m; j++ ) {

// Step 5
if( [originalString characterAtIndex: i-1] ==
   [comparisonString characterAtIndex: j-1] )
cost = 0;
else
cost = 1;

// Step 6
d[ j * n + i ] = [self smallestOf: d [ (j - 1) 
* n + i ] + 1
andOf: d[ j * n + i - 1 ] +  1
andOf: d[ (j - 1) * n + i
- 1 ] + cost ];

// This conditional adds Damerau transposition 
to Levenshtein distance
if( i1  j1  [originalString 
characterAtIndex: i-1] ==
   [comparisonString characterAtIndex: j-2] 
   [originalString characterAtIndex: i-2] ==
   [comparisonString characterAtIndex: j-1] )
{
d[ j * n + i] = [self smallestOf: d[ j 
* n + i ]
   andOf: d[ (j - 2) * n +
i - 2 ] + cost ];
}
}
//distance = d[ n * m - 1 ];

distance = d[ n * m - 1 ]/(float)n; //? More accurate... based 
on
length of the original string?

free( d );

return distance;
}
return 0.0;
}
___

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


who is currently the first responder? (iOS)

2011-06-29 Thread Roland King
Is there a way to find out what UIResponder is the current first responder, the 
one with the keyboard up? 

I have a number of editable fields, each on a cell of a table view which is in 
a UIViewController managed by a UINavigationController. There's a couple of 
other editable fields on there too, in the top bar. If the user hits the back 
button, or a button which pushes a new UIViewController on the stack or 
initiates some other view transition whilst one of those things is being 
edited, I want to make the edit commit before I leave the screen to get the 
model object in a consistent state. To do that I need to tell the first 
responder to resign, if I can figure out what it is. 

I didn't particularly want to iterate all the fields which could be onscreen or 
all the views in the hierarchy and tell them all to resign. Is there a way to 
find the current first responder? 

I did wonder about just telling the UIApplication itself to become, and then 
resign, first responder, but that doesn't feel quite 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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Fuzzy string matching

2011-06-29 Thread Ulf Dunkel

Hi Eric.


I have an application (iOS) that is doing speech to text. The
resulting string I'd like to fuzzy match against the user's onboard
music library, and play a song, album, genre, etc. as appropriate. I
am looking for a really good fuzzy string matching engine. I found
this: http://www.locayta.com/, not sure it's something I could use or
not. Also I found this code (but it's not quote accurate enough for
reliable results):

Any better ideas for a better fuzzy string match?


For me, the Levenshtein distance method has always worked fine. You can 
even offer an UI element (I'd suggest a slider) to let the user define a 
looser or tighter distance for better results.


---Ulf Dunkel
___

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: How Do I get informed when -showHelp: has been called?

2011-06-29 Thread Ulf Dunkel
I would really like to get a hint on this. Even a simple not possible 
would help. Thank you. :-)


- - - - -

Am 27.06.2011 22:58, schrieb Ulf Dunkel:

In a simple app of mine, I use the standard Help menu and MyApp Help
menu item, which is bound to -showHelp:.

I would like to have my AppDelegate being informed when the Help Viewer
has been launched and opened from this menu item.

It seems as if the method -showHelp: cannot be overridden. Which other
way can I use to receive any information when -showHelp: has been called?

TY in advance,
---Ulf Dunkel

___

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: problem with applying md5 to data

2011-06-29 Thread Wilker
Thanks Quincey, these things for sure will be a lot helpful, Im still pretty
new to Objective-C, but I will look in all of those things that you said,
thanks :)
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 5:13 AM, Quincey Morris quinceymor...@earthlink.net
 wrote:

 On Jun 29, 2011, at 00:27, Quincey Morris wrote:

[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
[file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 
[file closeFile];
 
  This is not the worst way to read the entire contents of a file into a
 NSData object, but it's pretty bad. :)
 
  It would be far easier and more efficient to use [NSData
 dataWithContentsOfFile: path options: NSDataReadingMapped |
 NSDataReadingUncached error: NULL];

 Er, two things.

 I didn't notice until after I posted that you weren't reading the whole
 file. So, sorry, pretty bad was too strong -- I'm upgrading my response to
 not the best. :)

 I think the way I suggested is still the best way, because (typically)
 using the NSDataReadingMapped means the file contents are mapped into
 virtual memory, so pages (4KB, or whatever the VM page size is) are not
 actually read until you try to access them.

 If you use CC_MD5_Init/Update (first part)/Update (last part)/Final instead
 of the convenience method that does it all, only the parts of the file you
 need will actually be read.

 NSDataReadingMapped is in general the most efficient way to read a file
 when you only need to read any part once, I think.

 The problem with NSFileHandle is that it pretty much sucks as a class. It
 doesn't return any errors, so if something goes wrong it's either going to
 throw an exception or just ignore it. IIRC it has no API contract regarding
 error reporting.

 Second thing...

 I forgot to point out that your code has a glaring bug. With your
 declarations, 'fileSize - CHUNK_SIZE' in 'MAX(0, fileSize - CHUNK_SIZE)' is
 an unsigned expression. It can't go negative, and so that statement isn't
 doing what it looks like it's doing.

 One more thing ...

 Since you have no release/retain calls, I'm assuming you're using garbage
 collection. If that's the case, then this line is very, very dangerous:

  return [SMEncodingUtilities md5HexDigestFromChar:[fileData bytes]
 withLength:(unsigned int)[fileData length]];

 You're passing an *interior* pointer to fileData's private storage, but the
 (compiler-optimized) lifetime of 'fileData' ends *before* the md5 method is
 entered, and so the object is subject to being collected *before* you've
 used the pointer. This will crash.

 In your code, the window of danger is pretty small. But it will crash
 eventually.

 The solution is to put a reference to the object after the call:

  NSString* result = [SMEncodingUtilities
 md5HexDigestFromChar:[fileData bytes] withLength:(unsigned int)[fileData
 length]];
  [fileData self];
  return result;

 It's a PITA, but you gotta be careful with NSData.


___

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: Fuzzy string matching

2011-06-29 Thread Eric E. Dolecki
Thanks for the reply, I've now found this:

http://www.merriampark.com/ldobjc.htm

Will try this out and see how it goes. It's close to something I
already had which I didn't think worked that great, but will try
anyway.

Eric



On Wed, Jun 29, 2011 at 9:19 AM, Ulf Dunkel dun...@calamus.net wrote:
 Hi Eric.

 I have an application (iOS) that is doing speech to text. The
 resulting string I'd like to fuzzy match against the user's onboard
 music library, and play a song, album, genre, etc. as appropriate. I
 am looking for a really good fuzzy string matching engine. I found
 this: http://www.locayta.com/, not sure it's something I could use or
 not. Also I found this code (but it's not quote accurate enough for
 reliable results):

 Any better ideas for a better fuzzy string match?

 For me, the Levenshtein distance method has always worked fine. You can even
 offer an UI element (I'd suggest a slider) to let the user define a looser
 or tighter distance for better results.

 ---Ulf Dunkel
 ___

 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/edolecki%40gmail.com

 This email sent to edole...@gmail.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:
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: problem with applying md5 to data

2011-06-29 Thread Wilker
Quincey, I did some changes following your recommendations, this is my
current version:

+(NSString *)generateHashFromPath:(NSString *)path {
const NSUInteger CHUNK_SIZE = 65536;
NSData *fileData = [NSData dataWithContentsOfFile:path
options:NSDataReadingMapped | NSDataReadingUncached error:NULL];

char buffer[CHUNK_SIZE];

CC_MD5_CTX md5;
CC_MD5_Init(md5);

[fileData getBytes:buffer range:NSMakeRange(0, CHUNK_SIZE)];
CC_MD5_Update(md5, buffer, CHUNK_SIZE);
[fileData getBytes:buffer range:NSMakeRange(MAX(0, [fileData length] -
CHUNK_SIZE), CHUNK_SIZE)];
CC_MD5_Update(md5, buffer, CHUNK_SIZE);

unsigned char digest[CC_MD5_DIGEST_LENGTH];

CC_MD5_Final(digest, md5);

NSMutableString *ret = [NSMutableString
stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

for (int i = 0; i  CC_MD5_DIGEST_LENGTH; i++) {
[ret appendFormat:@%02x, digest[i]];
}

return [ret lowercaseString];
}

Any other tip for improving it? (I know, I still need to handle the errors,
hehe, but anything else?)
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 10:31 AM, Wilker wilkerlu...@gmail.com wrote:

 Thanks Quincey, these things for sure will be a lot helpful, Im still
 pretty new to Objective-C, but I will look in all of those things that you
 said, thanks :)

 ---
 Wilker Lúcio
 http://about.me/wilkerlucio/bio
 Kajabi Consultant
 +55 81 82556600



 On Wed, Jun 29, 2011 at 5:13 AM, Quincey Morris 
 quinceymor...@earthlink.net wrote:

 On Jun 29, 2011, at 00:27, Quincey Morris wrote:

[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
[file seekToFileOffset:MAX(0, fileSize - CHUNK_SIZE)];
[fileData appendData:[file readDataOfLength:CHUNK_SIZE]];
 
[file closeFile];
 
  This is not the worst way to read the entire contents of a file into a
 NSData object, but it's pretty bad. :)
 
  It would be far easier and more efficient to use [NSData
 dataWithContentsOfFile: path options: NSDataReadingMapped |
 NSDataReadingUncached error: NULL];

 Er, two things.

 I didn't notice until after I posted that you weren't reading the whole
 file. So, sorry, pretty bad was too strong -- I'm upgrading my response to
 not the best. :)

 I think the way I suggested is still the best way, because (typically)
 using the NSDataReadingMapped means the file contents are mapped into
 virtual memory, so pages (4KB, or whatever the VM page size is) are not
 actually read until you try to access them.

 If you use CC_MD5_Init/Update (first part)/Update (last part)/Final
 instead of the convenience method that does it all, only the parts of the
 file you need will actually be read.

 NSDataReadingMapped is in general the most efficient way to read a file
 when you only need to read any part once, I think.

 The problem with NSFileHandle is that it pretty much sucks as a class. It
 doesn't return any errors, so if something goes wrong it's either going to
 throw an exception or just ignore it. IIRC it has no API contract regarding
 error reporting.

 Second thing...

 I forgot to point out that your code has a glaring bug. With your
 declarations, 'fileSize - CHUNK_SIZE' in 'MAX(0, fileSize - CHUNK_SIZE)' is
 an unsigned expression. It can't go negative, and so that statement isn't
 doing what it looks like it's doing.

 One more thing ...

 Since you have no release/retain calls, I'm assuming you're using garbage
 collection. If that's the case, then this line is very, very dangerous:

  return [SMEncodingUtilities md5HexDigestFromChar:[fileData bytes]
 withLength:(unsigned int)[fileData length]];

 You're passing an *interior* pointer to fileData's private storage, but
 the (compiler-optimized) lifetime of 'fileData' ends *before* the md5 method
 is entered, and so the object is subject to being collected *before* you've
 used the pointer. This will crash.

 In your code, the window of danger is pretty small. But it will crash
 eventually.

 The solution is to put a reference to the object after the call:

  NSString* result = [SMEncodingUtilities
 md5HexDigestFromChar:[fileData bytes] withLength:(unsigned int)[fileData
 length]];
  [fileData self];
  return result;

 It's a PITA, but you gotta be careful with NSData.



___

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: How Do I get informed when -showHelp: has been called?

2011-06-29 Thread Angus Hardie

On 29 Jun 2011, at 14:22, Ulf Dunkel wrote:

 I would really like to get a hint on this. Even a simple not possible would 
 help. Thank you. :-)
 
 - - - - -
 
 Am 27.06.2011 22:58, schrieb Ulf Dunkel:
 In a simple app of mine, I use the standard Help menu and MyApp Help
 menu item, which is bound to -showHelp:.
 
 I would like to have my AppDelegate being informed when the Help Viewer
 has been launched and opened from this menu item.
 
 It seems as if the method -showHelp: cannot be overridden. Which other
 way can I use to receive any information when -showHelp: has been called?
 
 TY in advance,
 ---Ulf Dunkel



I'm curious what you're trying to achieve here.


My first thought was that you could change the target of the menu item
so that it calls your own method, then call the original 
showHelp method with something like:

 [NSApp showHelp:sender]


This still might not actually display the help viewer 
for example if it had been removed from the system, or if something made it 
crash before it displayed.
I'm not sure what happens in those cases (an error in the log, or does it 
display an error alert?)
Not very likely perhaps though.


If you have to be more certain you might be able to view the active process 
list and observe
whether it contained the help viewer after the call to showHelp.

Alternatively maybe run a web server inside your app and make the help page 
load some object from it?

It depends on how certain you want to be I suppose. :-)

Perhaps others might have better ideas or could suggest another way of doing it.

Angus___

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: How Do I get informed when -showHelp: has been called?

2011-06-29 Thread Gerd Knops

On Jun 29, 2011, at 8:22 AM, Ulf Dunkel wrote:

 I would really like to get a hint on this. Even a simple not possible would 
 help. Thank you. :-)
 
 - - - - -
 
 Am 27.06.2011 22:58, schrieb Ulf Dunkel:
 In a simple app of mine, I use the standard Help menu and MyApp Help
 menu item, which is bound to -showHelp:.
 
 I would like to have my AppDelegate being informed when the Help Viewer
 has been launched and opened from this menu item.
 
 It seems as if the method -showHelp: cannot be overridden. Which other
 way can I use to receive any information when -showHelp: has been called?
 
What makes you think -showHelp: (in NSApplication) can not be overridden? Works 
fine here.

The possibly confusing part when subclassing NSApplication is how to make your 
app use that subclass. Typically this is done by setting a custom class (your 
subclass) to the Application object in the MainMenu nib file.

Gerd


___

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: Fuzzy string matching

2011-06-29 Thread Shawn Bakhtiar


Just out of curiosity...

Why not use extended regular expressions? Or am I missing something?



 From: edole...@gmail.com
 Date: Wed, 29 Jun 2011 09:33:44 -0400
 To: dun...@calamus.net
 CC: cocoa-dev@lists.apple.com
 Subject: Re: Fuzzy string matching
 
 Thanks for the reply, I've now found this:
 
 http://www.merriampark.com/ldobjc.htm
 
 Will try this out and see how it goes. It's close to something I
 already had which I didn't think worked that great, but will try
 anyway.
 
 Eric
 
 
 
 On Wed, Jun 29, 2011 at 9:19 AM, Ulf Dunkel dun...@calamus.net wrote:
  Hi Eric.
 
  I have an application (iOS) that is doing speech to text. The
  resulting string I'd like to fuzzy match against the user's onboard
  music library, and play a song, album, genre, etc. as appropriate. I
  am looking for a really good fuzzy string matching engine. I found
  this: http://www.locayta.com/, not sure it's something I could use or
  not. Also I found this code (but it's not quote accurate enough for
  reliable results):
 
  Any better ideas for a better fuzzy string match?
 
  For me, the Levenshtein distance method has always worked fine. You can even
  offer an UI element (I'd suggest a slider) to let the user define a looser
  or tighter distance for better results.
 
  ---Ulf Dunkel
  ___
 
  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/edolecki%40gmail.com
 
  This email sent to edole...@gmail.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:
 http://lists.apple.com/mailman/options/cocoa-dev/shashaness%40hotmail.com
 
 This email sent to shashan...@hotmail.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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: who is currently the first responder? (iOS)

2011-06-29 Thread Matt Neuburg
On Wed, 29 Jun 2011 21:12:50 +0800, Roland King r...@rols.org said:
Is there a way to find out what UIResponder is the current first responder, 
the one with the keyboard up? 

No. I devote some space to ranting about this in my book. The app obviously 
*knows* who the first responder is, so why won't it tell you?

My workaround is to implement delegate methods on all my UITextFields and store 
a reference to the text field in an instance variable when it starts being 
edited. Oh, and as I warn in the book, do NOT name that instance variable 
firstResponder or your app will fall to its knees; guess how I found *that* 
out? :)

I want to make the edit commit

Oh. Well, if that's your only problem, then all you have to do is call 
endEditing: on the superview.

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: How to assign a method for touch event to a UIImageView?

2011-06-29 Thread Matt Neuburg
On Fri, 24 Jun 2011 22:26:42 +0200, Jonathan Chac?n Barbero 
tyflos2...@gmail.com said:

I want to execute a method when the user touches a UIImageView.

In my book, I actually give a solution to this (in the Touch Delivery section 
of the Touches chapter): set the UIImageView's userInteractionEnabled to YES 
and attach a UITapGestureRecognizer to it or to its superview. If you attach 
the UITapGestureRecognizer to the superview, you can use hit-testing to 
determine whether the UIImageView was tapped:

CGPoint p = [g locationOfTouch:0 inView:self]; // g is the gesture recognizer
UIView* v = [self hitTest:p withEvent:nil];

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 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: who is currently the first responder? (iOS)

2011-06-29 Thread Roland King

On 29-Jun-2011, at 11:56 PM, Matt Neuburg wrote:

 On Wed, 29 Jun 2011 21:12:50 +0800, Roland King r...@rols.org said:
 Is there a way to find out what UIResponder is the current first responder, 
 the one with the keyboard up? 
 
 No. I devote some space to ranting about this in my book. The app obviously 
 *knows* who the first responder is, so why won't it tell you?

Yeah annoying isn't it - I'll file a bug report about that. Googling found a 
guy who's app was rejected because he found a method which returned it, could 
do with that being public. 

 
 My workaround is to implement delegate methods on all my UITextFields and 
 store a reference to the text field in an instance variable when it starts 
 being edited. Oh, and as I warn in the book, do NOT name that instance 
 variable firstResponder or your app will fall to its knees; guess how I 
 found *that* out? :)
 
 I want to make the edit commit
 
 Oh. Well, if that's your only problem, then all you have to do is call 
 endEditing: on the superview.

aagh - thanks - I'd been looking at methods on the view controller for it, like 
setEditing: etc., didn't find endEditing on the view itself, that should do the 
trick. The documentation for that says it goes through the view hierarchy 
finding the text field which is the first responder, so it does what you would 
naively do, and in this case, they're all text fields so that's ok. 

let me go put that in and try it out

thanks

 
 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: who is currently the first responder? (iOS)

2011-06-29 Thread Alex Kac
File a doc bug :)

-- 
Alex Kac CEO/Founder

On Jun 29, 2011, at 11:10 AM, Matt Neuburg m...@tidbits.com wrote:

 Actually it works for more than text fields; another case of poor 
 documentation. m.
___

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


Activate app but bring only *one* window to the front

2011-06-29 Thread Jerry Krinock
• App is running with several windows open but is not frontmost.
• It receives an interapplication message which requires that a new window be 
opened and brought to the front.

-[NSApplication activateIgnoringOtherApps:] brings *all* of app's windows to 
the front.

How can I activate this app but bring *only* the new window to the front?  
Other windows should remain at their current order.

Thank you,

Jerry Krinock

___

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: Activate app but bring only *one* window to the front

2011-06-29 Thread Kyle Sluder
On Wed, Jun 29, 2011 at 10:07 AM, Jerry Krinock je...@ieee.org wrote:
 • App is running with several windows open but is not frontmost.
 • It receives an interapplication message which requires that a new window be 
 opened and brought to the front.

 -[NSApplication activateIgnoringOtherApps:] brings *all* of app's windows to 
 the front.

 How can I activate this app but bring *only* the new window to the front?  
 Other windows should remain at their current order.

Never tried it, but +[NSRunningApplication activateWithOptions:] looks
promising.

--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: Activate app but bring only *one* window to the front

2011-06-29 Thread Kyle Sluder
On Wed, Jun 29, 2011 at 10:11 AM, Kyle Sluder kyle.slu...@gmail.com wrote:
 Never tried it, but +[NSRunningApplication activateWithOptions:] looks
 promising.

Er, make that -[NSRunningApplication activateWithOptions:]. Combine
that with +[NSRunningApplication currentApplication].

--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 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: problem with applying md5 to data

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 07:08, Wilker wrote:

 char buffer[CHUNK_SIZE];

 [fileData getBytes:buffer range:NSMakeRange(0, CHUNK_SIZE)];
 CC_MD5_Update(md5, buffer, CHUNK_SIZE);
 [fileData getBytes:buffer range:NSMakeRange(MAX(0, [fileData length] - 
 CHUNK_SIZE), CHUNK_SIZE)];
 CC_MD5_Update(md5, buffer, CHUNK_SIZE);

Personally, having tried to get the file reads as cheaply as possible**, I'd 
just do this:

const uint8_t* buffer = [fileData bytes];
// calculate byteLength and byteOffset (see below)

CC_MD5_Update(md5, buffer, byteLength);
CC_MD5_Update(md5, buffer + byteOffset, byteLength);

[fileData self];

to avoid copying the raw data unnecessarily.

Your code still has the bug in the MAX parameters (if [fileData length]  
CHUNK_SIZE, then [fileData length] - CHUNK_SIZE is a *very* large positive 
number), and you've introduced a new one -- 'getBytes:range:' will crash if the 
range goes past the end of the NSData data, so I'd calculate the length and 
offset like this:

NSUInteger byteLength = [fileData length];
NSUInteger byteOffset = 0;

if (byteLength  CHUNK_SIZE) { // ***
byteLength = CHUNK_SIZE;
byteOffset = byteLength - CHUNK_SIZE;
}



** There are some drawbacks to using very large stack-based structures. At 
least:

a. If this code is ever part of a background thread, the default maximum stack 
size isn't large enough to accommodate 65K data structures.

b. If this is running under garbage collection, the collector must scan the 
entire 65K every time it runs, uselessly and wastefully.

What's the usual way to solve these problems? To move the data structure off 
the stack into the heap. But you already have the data in the heap, in your 
NSData object.

*** Someone once pointed out on this list that you should never use MIN and MAX 
(and other such convenience macros) in production code, because you are never 
quite certain how they're implemented (in terms of handling mismatched sign 
expressions, for example) and how they might be implemented on some future 
platform you might want to port this code to. Therefore, he said, you should 
write the code you want, not hope for the code you need. I think maybe his 
point was a little obsessive, but I have to admit I now cringe and hesitate 
before writing MIN or MAX. :)___

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: problem with applying md5 to data

2011-06-29 Thread Wilker
Thanks again Quincey.

Just for curiousity, if I do the line:

 const uint8_t* buffer = [fileData bytes];

it will not read the entire file? or these address are pointed direct on
disk so they are load on demand?
also, just to mean if I understand here:

CC_MD5_Update(md5, buffer + byteOffset, byteLength);

in the sum buffer + byteOffset, in case, adding a number to an array
pointer will change it offset?
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 2:53 PM, Quincey Morris quinceymor...@earthlink.net
 wrote:

 On Jun 29, 2011, at 07:08, Wilker wrote:

  char buffer[CHUNK_SIZE];

  [fileData getBytes:buffer range:NSMakeRange(0, CHUNK_SIZE)];
  CC_MD5_Update(md5, buffer, CHUNK_SIZE);
  [fileData getBytes:buffer range:NSMakeRange(MAX(0, [fileData length]
 - CHUNK_SIZE), CHUNK_SIZE)];
  CC_MD5_Update(md5, buffer, CHUNK_SIZE);

 Personally, having tried to get the file reads as cheaply as possible**,
 I'd just do this:

const uint8_t* buffer = [fileData bytes];
// calculate byteLength and byteOffset (see below)

CC_MD5_Update(md5, buffer, byteLength);
CC_MD5_Update(md5, buffer + byteOffset, byteLength);

[fileData self];

 to avoid copying the raw data unnecessarily.

 Your code still has the bug in the MAX parameters (if [fileData length] 
 CHUNK_SIZE, then [fileData length] - CHUNK_SIZE is a *very* large positive
 number), and you've introduced a new one -- 'getBytes:range:' will crash if
 the range goes past the end of the NSData data, so I'd calculate the length
 and offset like this:

NSUInteger byteLength = [fileData length];
NSUInteger byteOffset = 0;

if (byteLength  CHUNK_SIZE) { // ***
byteLength = CHUNK_SIZE;
byteOffset = byteLength - CHUNK_SIZE;
}



 ** There are some drawbacks to using very large stack-based structures. At
 least:

 a. If this code is ever part of a background thread, the default maximum
 stack size isn't large enough to accommodate 65K data structures.

 b. If this is running under garbage collection, the collector must scan the
 entire 65K every time it runs, uselessly and wastefully.

 What's the usual way to solve these problems? To move the data structure
 off the stack into the heap. But you already have the data in the heap, in
 your NSData object.

 *** Someone once pointed out on this list that you should never use MIN and
 MAX (and other such convenience macros) in production code, because you are
 never quite certain how they're implemented (in terms of handling mismatched
 sign expressions, for example) and how they might be implemented on some
 future platform you might want to port this code to. Therefore, he said, you
 should write the code you want, not hope for the code you need. I think
 maybe his point was a little obsessive, but I have to admit I now cringe and
 hesitate before writing MIN or MAX. :)
___

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


Display Letterboxing Pillarboxing

2011-06-29 Thread Richard Somers
In System Preferences a user may select a specific display resolution.

Some display resolutions will stretch the visible area to fill the display as 
needed. But some display resolutions will pillarbox where a black bar is placed 
on the left and right of the visible area.

Is it possible to programmatically detect when the current display resolution 
is letterboxing or pillarboxing?

The Quartz Display Services Reference does not seem to have any functions that 
reveal this information.

http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html

--Richard

___

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: problem with applying md5 to data

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 11:32, Wilker wrote:

 Just for curiousity, if I do the line:
 
  const uint8_t* buffer = [fileData bytes];
 
 it will not read the entire file? or these address are pointed direct on disk 
 so they are load on demand?

[fileData bytes] is a pointer to some memory address or other, in your 
application's virtual memory address space. The actual pages of data don't 
exist yet, they are indeed loaded on demand. The demand will happen when 
CC_MD5_Update tries to retrieve bytes to update its calculations. As its 
internal pointer increments into each new page, its data accesses will cause VM 
faults, which will cause the pages to be read from disk, which in this case is 
your video file.

That's why this is efficient. A normal read will transfer pages of data into 
the system's disk cache, then transfer some of it again into your application's 
address space, and if those pages in your address space happen to be swapped 
out sometime, your data is written *back* to disk (in the system VM backing 
store) for later rereading. Using mapped reads with no caching avoids all of 
that.

 also, just to mean if I understand here:
 
 CC_MD5_Update(md5, buffer + byteOffset, byteLength);
 
 in the sum buffer + byteOffset, in case, adding a number to an array 
 pointer will change it offset?

'buffer' is not an array, it's just a pointer. It's a pointer to an array of 
bytes, if you choose to think of it that way, but so are all pointers, if you 
choose to think of them that way.

Think of it this way. You were using 
'getBytes:range:NSMakeRange(offset,length)' to copy the bytes to a local 
buffer. That buffer must have copied the bytes *from* somewhere. The place 
where the bytes are being copied from is, literally, '[fileData bytes] + 
offset', and NSData's API makes it perfectly legal to go to the source 
yourself.___

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: problem with applying md5 to data

2011-06-29 Thread Wilker
Nice :)

This is my latest code, I mean it should be right now, hehe (and yeth, Im
using GC):

+(NSString *)generateHashFromPath:(NSString *)path {
const NSUInteger CHUNK_SIZE = 65536;

NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfFile:path
options:NSDataReadingMapped | NSDataReadingUncached error:error];

if (error) {
return nil;
}

const uint8_t* buffer = [fileData bytes];

NSUInteger byteLength = [fileData length];
NSUInteger byteOffset = 0;

if (byteLength  CHUNK_SIZE) {
byteOffset = byteLength - CHUNK_SIZE;
byteLength = CHUNK_SIZE;
}

CC_MD5_CTX md5;
CC_MD5_Init(md5);

CC_MD5_Update(md5, buffer, (unsigned int) byteLength);
CC_MD5_Update(md5, buffer + byteOffset, (unsigned int) byteLength);

unsigned char digest[CC_MD5_DIGEST_LENGTH];

CC_MD5_Final(digest, md5);

NSMutableString *ret = [NSMutableString
stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

for (int i = 0; i  CC_MD5_DIGEST_LENGTH; i++) {
[ret appendFormat:@%02x, digest[i]];
}

return [ret lowercaseString];
}

I tried it against a video of 8.5GB, stored on external drive (at wifi with
Airport Extreme), and it's blazing fast :)
Thanks a lot
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 4:18 PM, Quincey Morris quinceymor...@earthlink.net
 wrote:

 On Jun 29, 2011, at 11:32, Wilker wrote:

  Just for curiousity, if I do the line:
 
   const uint8_t* buffer = [fileData bytes];
 
  it will not read the entire file? or these address are pointed direct on
 disk so they are load on demand?

 [fileData bytes] is a pointer to some memory address or other, in your
 application's virtual memory address space. The actual pages of data don't
 exist yet, they are indeed loaded on demand. The demand will happen when
 CC_MD5_Update tries to retrieve bytes to update its calculations. As its
 internal pointer increments into each new page, its data accesses will cause
 VM faults, which will cause the pages to be read from disk, which in this
 case is your video file.

 That's why this is efficient. A normal read will transfer pages of data
 into the system's disk cache, then transfer some of it again into your
 application's address space, and if those pages in your address space happen
 to be swapped out sometime, your data is written *back* to disk (in the
 system VM backing store) for later rereading. Using mapped reads with no
 caching avoids all of that.

  also, just to mean if I understand here:
 
  CC_MD5_Update(md5, buffer + byteOffset, byteLength);
 
  in the sum buffer + byteOffset, in case, adding a number to an array
 pointer will change it offset?

 'buffer' is not an array, it's just a pointer. It's a pointer to an array
 of bytes, if you choose to think of it that way, but so are all pointers, if
 you choose to think of them that way.

 Think of it this way. You were using
 'getBytes:range:NSMakeRange(offset,length)' to copy the bytes to a local
 buffer. That buffer must have copied the bytes *from* somewhere. The place
 where the bytes are being copied from is, literally, '[fileData bytes] +
 offset', and NSData's API makes it perfectly legal to go to the source
 yourself.
___

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: Display Letterboxing Pillarboxing

2011-06-29 Thread Nick Zitzmann

On Jun 29, 2011, at 1:04 PM, Richard Somers wrote:

 In System Preferences a user may select a specific display resolution.
 
 Some display resolutions will stretch the visible area to fill the display as 
 needed. But some display resolutions will pillarbox where a black bar is 
 placed on the left and right of the visible area.
 
 Is it possible to programmatically detect when the current display resolution 
 is letterboxing or pillarboxing?

No, because that's up the monitor to decide what to do when that happens. For 
example, if the user has a 16:10 aspect ratio monitor and sets the resolution 
to 1080p instead of 1200p, then some monitors will stretch the image 
vertically, some will preserve the aspect ratio by letterboxing the image, and 
some will have a setting that lets the user decide how to handle the 
situation*. Unless the user is using one of Apple's built-in laptop displays, 
which always stretch the image IIRC, you can't count on this being set one way 
or the other.

Nick Zitzmann
http://www.chronosnet.com/

* Yes, this is a wedge issue for a lot of people...

___

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


Re: problem with applying md5 to data

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 12:26, Wilker wrote:

 +(NSString *)generateHashFromPath:(NSString *)path {
 const NSUInteger CHUNK_SIZE = 65536;
 
 NSError *error = nil;
 NSData *fileData = [NSData dataWithContentsOfFile:path 
 options:NSDataReadingMapped | NSDataReadingUncached error:error];
 
 if (error) {
 return nil;
 }
 
 const uint8_t* buffer = [fileData bytes];
 
 NSUInteger byteLength = [fileData length];
 NSUInteger byteOffset = 0;
 
 if (byteLength  CHUNK_SIZE) {
 byteOffset = byteLength - CHUNK_SIZE;
 byteLength = CHUNK_SIZE;
 }
 
 CC_MD5_CTX md5;
 CC_MD5_Init(md5);
 
 CC_MD5_Update(md5, buffer, (unsigned int) byteLength);
 CC_MD5_Update(md5, buffer + byteOffset, (unsigned int) byteLength);
 
 unsigned char digest[CC_MD5_DIGEST_LENGTH];
 
 CC_MD5_Final(digest, md5);
 
 NSMutableString *ret = [NSMutableString 
 stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
 
 for (int i = 0; i  CC_MD5_DIGEST_LENGTH; i++) {
 [ret appendFormat:@%02x, digest[i]];
 }
 
 return [ret lowercaseString];
 }

This looks good to me, but since we're noodling around various topics here, let 
me nitpick at some details:

1. Format specifier '%x' produces lower case letters, so you don't need to 
lowercase the returned string. If you'd happened to want uppercase, there's 
'%X'.

If you're just trying to return an immutable string, there are three possible 
answers:

a. Don't bother. It's almost always fine to return a NSMutableString when your 
method's API's return type says NSString.

b. Return '[ret copy]'. That allows NSString to do the fastest copy of the 
character data that it's capable of. The result is an immutable string.

c. Go back to the way you first did it, where you spelled out the entire format 
string, so you don't ever create a NSMutableString.

2. There still a flashing danger signal in your code. Pretty much any time you 
have to cast a scalar type, your code gets smelly 
(http://en.wikipedia.org/wiki/Code_smell).

If you consult the CC_MD5 man page, you'll see that the length parameter type 
is officially CC_LONG.  What happens if byteLength is bigger than the largest 
possible CC_LONG? (In other words, what happens if your file is bigger than 
4GB?)

WIth this code, the consequences would not be catastrophic, but the wrong 
digest would likely be calculated.

So, declare 'byteLength' as type CC_LONG and get rid of those ad hoc casts. You 
might still need a cast, but pair it with a safety check:

CC_LONG byteLength = (CC_LONG) ([file length]  CHUNK_SIZE ? CHUNK_SIZE 
: [file length]);

That messes up the setting of byteOffset, so you need to change that to 
something like:

NSUInteger byteOffset = [file length]  CHUNK_SIZE ? [file length] - 
CHUNK_SIZE : 0;

Depending on your aesthetic tastes, you might actually want to do:

NSUInteger fileLength = [fileData length];
CC_LONG byteLength = (CC_LONG) (fileLength  CHUNK_SIZE ? CHUNK_SIZE : 
fileLength);
NSUInteger byteOffset = fileLength  CHUNK_SIZE ? fileLength - 
CHUNK_SIZE : 0;

Anyone reading your code can now see that the cast is harmless, because you've 
explicitly checked for the error condition.

 I tried it against a video of 8.5GB, stored on external drive (at wifi with 
 Airport Extreme), and it's blazing fast :)

This is a remarkable statement, if you think about it. My pitch for 
'NSDataReadingMapped' relied on the assumption that the file was local. If 
NSData is really providing the effect of memory mapping with a remote file, 
it's really doing a *lot* of heavy lifting for you.

That's really quite a surprising result.




___

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: Help with relationship objects

2011-06-29 Thread Brad Stone
Quincey, that helps.  Thanks

On Jun 28, 2011, at 1:36 PM, Quincey Morris wrote:

 On Jun 28, 2011, at 08:40, Brad Stone wrote:
 
 I get the below.  Notice the new SRTodoEntity is properly in the todos 
 relationship but there's also a reference to it outside of the SRNoteEntity. 
  Intuitively, I would think there should be only one reference to it inside 
 SRNoteEntity.This is my confusion.  Why is it reference twice?  How can 
 I prevent that from happening if this isn't normal?
 
 po [[self managedObjectContext] registeredObjects]
 {(
 Note uid:330961758011065
  creationDate:2009-09-05 13:21:54 -0400
  modificationDate:2009-09-06 12:41:02 -0400
  todos:Relationship objects for {(
  SRTodoEntity: 0x200483d80 (entity: SRTodoEntity; id: 0x2004121e0 
 x-coredata://614245CF-F03E-4F43-9D7F-98CDCB2899FA/SRTodoEntity/p1 ; data: {
  note = 0x2002c4e60 
 x-coredata://614245CF-F03E-4F43-9D7F-98CDCB2899FA/SRNoteEntity/p1;
  todoViewData = nil;
  })
  )} on 0x200448360
 noteData:538
 
 SRTodoEntity: 0x200483d80 (entity: SRTodoEntity; id: 0x2004121e0 
 x-coredata://614245CF-F03E-4F43-9D7F-98CDCB2899FA/SRTodoEntity/p1 ; data: {
  note = 0x2002c4e60 
 x-coredata://614245CF-F03E-4F43-9D7F-98CDCB2899FA/SRNoteEntity/p1;
  todoViewData = nil;
 })
 )}
 
 You've kinda got hold of the wrong end of this. Core Data is an object graph, 
 certainly, and any pointer to a managed object is a reference to the 
 object. There are references to these objects all over your code -- every 
 stack variable pointer is a reference. In the above example, a reference to 
 the Todo object exists inside the set of references that represents Note's 
 relationship to its Todo's. That makes it a really important reference, but 
 it's certainly never the only one.
 
 By sending a 'registeredObjects' message to the managedObjectContext (which 
 is *not* an object in the object graph), you've asked it to construct a 
 collection (a set, as it happens) of references to Core Data objects it knows 
 about. There's no *relationship* from the MOC to the managed objects, it's 
 just the MOC's job to know what managed objects are currently in memory.
 
 

___

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


Using Multi-Gesture events with Carbon

2011-06-29 Thread Abdul Sowayan
Hi folks,

I have a carbon based application that we are converting overtime to Cocoa. 
What I would like to do, if possible, is to incorporate multi-gesture events 
(such as magnify event) into my carbon application. I can see that NSResponder 
has magnifyWithEvent: selector. I am wondering if there is anyway to do so. Any 
feedback on how to do so would be greatly appreciated.

Thanks,
Abdul
___

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: problem with applying md5 to data

2011-06-29 Thread Wilker
Thanks :)

I will make the conversion to CC_LONG to be more clear, but about the bug, I
mean it will be impossible to happen on this case, since the max length will
be always 64kb :)

About the remote thing, I mean its more low level things, the HD is just
mounted as an Volume (on /Volumes/Wilker-1), so, I mean the handling on this
case should be transparent, the low level drivers should take care of it :)

I learned a lot from this thread, thanks :)
---
Wilker Lúcio
http://about.me/wilkerlucio/bio
Kajabi Consultant
+55 81 82556600



On Wed, Jun 29, 2011 at 5:31 PM, Quincey Morris quinceymor...@earthlink.net
 wrote:

 On Jun 29, 2011, at 12:26, Wilker wrote:

  +(NSString *)generateHashFromPath:(NSString *)path {
  const NSUInteger CHUNK_SIZE = 65536;
 
  NSError *error = nil;
  NSData *fileData = [NSData dataWithContentsOfFile:path
 options:NSDataReadingMapped | NSDataReadingUncached error:error];
 
  if (error) {
  return nil;
  }
 
  const uint8_t* buffer = [fileData bytes];
 
  NSUInteger byteLength = [fileData length];
  NSUInteger byteOffset = 0;
 
  if (byteLength  CHUNK_SIZE) {
  byteOffset = byteLength - CHUNK_SIZE;
  byteLength = CHUNK_SIZE;
  }
 
  CC_MD5_CTX md5;
  CC_MD5_Init(md5);
 
  CC_MD5_Update(md5, buffer, (unsigned int) byteLength);
  CC_MD5_Update(md5, buffer + byteOffset, (unsigned int) byteLength);
 
  unsigned char digest[CC_MD5_DIGEST_LENGTH];
 
  CC_MD5_Final(digest, md5);
 
  NSMutableString *ret = [NSMutableString
 stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
 
  for (int i = 0; i  CC_MD5_DIGEST_LENGTH; i++) {
  [ret appendFormat:@%02x, digest[i]];
  }
 
  return [ret lowercaseString];
  }

 This looks good to me, but since we're noodling around various topics here,
 let me nitpick at some details:

 1. Format specifier '%x' produces lower case letters, so you don't need to
 lowercase the returned string. If you'd happened to want uppercase, there's
 '%X'.

 If you're just trying to return an immutable string, there are three
 possible answers:

 a. Don't bother. It's almost always fine to return a NSMutableString when
 your method's API's return type says NSString.

 b. Return '[ret copy]'. That allows NSString to do the fastest copy of the
 character data that it's capable of. The result is an immutable string.

 c. Go back to the way you first did it, where you spelled out the entire
 format string, so you don't ever create a NSMutableString.

 2. There still a flashing danger signal in your code. Pretty much any time
 you have to cast a scalar type, your code gets smelly (
 http://en.wikipedia.org/wiki/Code_smell).

 If you consult the CC_MD5 man page, you'll see that the length parameter
 type is officially CC_LONG.  What happens if byteLength is bigger than the
 largest possible CC_LONG? (In other words, what happens if your file is
 bigger than 4GB?)

 WIth this code, the consequences would not be catastrophic, but the wrong
 digest would likely be calculated.

 So, declare 'byteLength' as type CC_LONG and get rid of those ad hoc casts.
 You might still need a cast, but pair it with a safety check:

CC_LONG byteLength = (CC_LONG) ([file length]  CHUNK_SIZE ?
 CHUNK_SIZE : [file length]);

 That messes up the setting of byteOffset, so you need to change that to
 something like:

NSUInteger byteOffset = [file length]  CHUNK_SIZE ? [file length] -
 CHUNK_SIZE : 0;

 Depending on your aesthetic tastes, you might actually want to do:

NSUInteger fileLength = [fileData length];
CC_LONG byteLength = (CC_LONG) (fileLength  CHUNK_SIZE ? CHUNK_SIZE
 : fileLength);
NSUInteger byteOffset = fileLength  CHUNK_SIZE ? fileLength -
 CHUNK_SIZE : 0;

 Anyone reading your code can now see that the cast is harmless, because
 you've explicitly checked for the error condition.

  I tried it against a video of 8.5GB, stored on external drive (at wifi
 with Airport Extreme), and it's blazing fast :)

 This is a remarkable statement, if you think about it. My pitch for
 'NSDataReadingMapped' relied on the assumption that the file was local. If
 NSData is really providing the effect of memory mapping with a remote file,
 it's really doing a *lot* of heavy lifting for you.

 That's really quite a surprising result.





___

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


Receive custom url without bringing app to front?

2011-06-29 Thread Jerry Krinock
When I install a custom URL handler like this:

NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager] ;
[aem setEventHandler:self
 andSelector:@selector(handleGetURLEvent:withReplyEvent:)
   forEventClass:kInternetEventClass
  andEventID:kAEGetURL] ;

even if I change my handler to no-op like this,

- (void)handleGetURLEvent:(NSAppleEventDescriptor*)event
   withReplyEvent:(NSAppleEventDescriptor*)replyEvent {
return ;
...
}

still when such custom URL is received, the system still brings all of the 
app's windows to the front.  I want the app to receive the message silently and 
then I'll display a window if needed.

I was wondering if anyone knows any way to change the activation behavior.  
I've set breakpoints on -[NSApplication activateIgoringOtherApps:] and also 
NSWindow methods one would use to front or display a window, but they never 
break.  It's like Apple is using some master 'activate' switch under the hood.

Yes, I know how to fix this by using a less cheesy method of interapplication 
communication, but I'm trying to be lazy.  Another alternative is to 
re-activate the prior frontmost app, or hide the app, after it activates, but 
that looks pretty bad.  To truly restore the user's workspace I'd need an API 
which gives the ordering of windows on the screen relative to those of other 
apps, but I've never been able to find such API.

Thanks,

Jerry Krinock

___

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


dealloc and scarce resources

2011-06-29 Thread James Merkel
In another thread, someone referenced the Memory Management  
Programming Guide:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ 
MemoryMgmt/Articles/mmPractical.html%23//apple_ref/doc/uid/ 
TP40004447-1000922-BABBFBGJ


In the Guide it says:

You should typically not manage scarce resources such as file  
descriptors, network connections, and buffers or caches in a dealloc  
method. In particular, you should not design classes so that dealloc  
will be invoked when you think it will be invoked. Invocation of  
dealloc might be delayed or sidestepped, either because of a bug or  
because of application tear-down.
Instead, if you have a class whose instances manage scarce resources,  
you should design your application such that you know when you no  
longer need the resources and can then tell the instance to “clean up”  
at that point. You would typically then release the instance, and  
dealloc would follow, but you will not suffer additional problems if  
it does not.


In my code I close a file in the dealloc method -- so I guess that's a  
file descriptor. I opened the file in the init method, so it seemed  
logical to close it in the dealloc method.
Also, not to be facetious, if I have a bug in my code, wouldn't I fix  
it? Granted, at application tear-down, if the file is still open, it  
won't be closed because dealloc won't be called. But again that comes  
under the heading of a bug in the code. So I don't understand this  
injunction.


Jim Merkel___

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: Receive custom url without bringing app to front?

2011-06-29 Thread Ken Thomases
On Jun 29, 2011, at 7:32 PM, Jerry Krinock wrote:

 When I install a custom URL handler like this:
 
 NSAppleEventManager *aem = [NSAppleEventManager sharedAppleEventManager] ;
 [aem setEventHandler:self
 andSelector:@selector(handleGetURLEvent:withReplyEvent:)
   forEventClass:kInternetEventClass
  andEventID:kAEGetURL] ;

 still when such custom URL is received, the system still brings all of the 
 app's windows to the front.  I want the app to receive the message silently 
 and then I'll display a window if needed.
 
 I was wondering if anyone knows any way to change the activation behavior.  
 I've set breakpoints on -[NSApplication activateIgoringOtherApps:] and also 
 NSWindow methods one would use to front or display a window, but they never 
 break.  It's like Apple is using some master 'activate' switch under the hood.

The app doesn't activate itself.  It is being activated by Launch Services, in 
another process -- either the program which used Launch Services or launchd or 
some other system agent.

Being asked to open a URL is analogous to being asked to open a document (and 
identical for file URLs), and your app is brought forward for the same reason.

You could use a background-only sub-application to receive the URL and then 
pass it to your main application using some other IPC mechanism (e.g. 
Distributed Objects).  I suppose you could even forward the Apple Event 
directly.  Either way, your sub-application would have to launch your main 
application if it weren't already running.

Regards,
Ken

___

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: dealloc and scarce resources

2011-06-29 Thread Wim Lewis

On 29 Jun 2011, at 5:43 PM, James Merkel wrote:
 In the [Memory Management Programming Guide] it says:
 
 You should typically not manage scarce resources such as file descriptors, 
 network connections, and buffers or caches in a dealloc method. In 
 particular, you should not design classes so that dealloc will be invoked 
 when you think it will be invoked. Invocation of dealloc might be delayed or 
 sidestepped, either because of a bug or because of application tear-down.
 Instead, if you have a class whose instances manage scarce resources, you 
 should design your application such that you know when you no longer need the 
 resources and can then tell the instance to “clean up” at that point. You 
 would typically then release the instance, and dealloc would follow, but you 
 will not suffer additional problems if it does not.
 
 In my code I close a file in the dealloc method -- so I guess that's a file 
 descriptor. I opened the file in the init method, so it seemed logical to 
 close it in the dealloc method.
 Also, not to be facetious, if I have a bug in my code, wouldn't I fix it? 
 Granted, at application tear-down, if the file is still open, it won't be 
 closed because dealloc won't be called. But again that comes under the 
 heading of a bug in the code. So I don't understand this injunction.

I don't think it should be treated as a hard rule, but I think it is good 
advice most of the time, or at least a good starting position.

One way to look at it is that for most objects you're not supposed to assume 
very much about their lifetime. You know they exist as long as you have a 
refcount to them, but they *may* continue to exist after you release them. This 
is the semantic of -release. You may happen to know, in a particular piece of 
code, that you have the only reference to something and it will be dealloced 
with a given release. But thinking of release as equivalent to dealloc will get 
you into trouble.

Even ignoring GC (which makes dealloc/finalize even more uncertain), you might 
end up stashing a reference to that object somewhere else, extending its 
lifetime. Maybe it's in an NSNotification or an undo stack or a debug log, or 
there's a situation where your autorelease pool lasts longer than you expect 
(perhaps you are dealing with a bunch of files in a loop as you load or save a 
document, eg). In my experience it isn't *usually* a problem of leaking the 
file handles entirely; it's a problem if I temporarily accumulate too many of 
them, or if I need the file handle (or socket or...) to be closed before I do 
some operation, and simply calling -release isn't normally a guarantee of that.

My preferred approach is to have a -close or -invalidate method that releases 
resources, breaks retain cycles, etc.. If -invalidate isn't called before 
dealloc, that's OK, but I can also call -invalidate explicitly if I know I want 
to tear down the object at a given time.

I think there are cases where the indefinite lifetime *is* what you want, if 
you have objects that can lazily fault something in from disk, or which 
encapsulate a sharable server connection, or etc. But those objects should be 
the exception, so that you can be especially aware of lifecycle issues in any 
code that deals with them. And even so, I usually end up having to give them an 
-invalidate method eventually, to deal with some odd situation.


___

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: dealloc and scarce resources

2011-06-29 Thread James Merkel


On Jun 29, 2011, at 7:17 PM, Wim Lewis wrote:



On 29 Jun 2011, at 5:43 PM, James Merkel wrote:

In the [Memory Management Programming Guide] it says:

You should typically not manage scarce resources such as file  
descriptors, network connections, and buffers or caches in a  
dealloc method. In particular, you should not design classes so  
that dealloc will be invoked when you think it will be invoked.  
Invocation of dealloc might be delayed or sidestepped, either  
because of a bug or because of application tear-down.
Instead, if you have a class whose instances manage scarce  
resources, you should design your application such that you know  
when you no longer need the resources and can then tell the  
instance to “clean up” at that point. You would typically then  
release the instance, and dealloc would follow, but you will not  
suffer additional problems if it does not.


In my code I close a file in the dealloc method -- so I guess  
that's a file descriptor. I opened the file in the init method, so  
it seemed logical to close it in the dealloc method.
Also, not to be facetious, if I have a bug in my code, wouldn't I  
fix it? Granted, at application tear-down, if the file is still  
open, it won't be closed because dealloc won't be called. But again  
that comes under the heading of a bug in the code. So I don't  
understand this injunction.


I don't think it should be treated as a hard rule, but I think it is  
good advice most of the time, or at least a good starting position.


One way to look at it is that for most objects you're not supposed  
to assume very much about their lifetime. You know they exist as  
long as you have a refcount to them, but they *may* continue to  
exist after you release them. This is the semantic of -release. You  
may happen to know, in a particular piece of code, that you have the  
only reference to something and it will be dealloced with a given  
release. But thinking of release as equivalent to dealloc will get  
you into trouble.


Even ignoring GC (which makes dealloc/finalize even more uncertain),  
you might end up stashing a reference to that object somewhere else,  
extending its lifetime. Maybe it's in an NSNotification or an undo  
stack or a debug log, or there's a situation where your autorelease  
pool lasts longer than you expect (perhaps you are dealing with a  
bunch of files in a loop as you load or save a document, eg). In my  
experience it isn't *usually* a problem of leaking the file handles  
entirely; it's a problem if I temporarily accumulate too many of  
them, or if I need the file handle (or socket or...) to be closed  
before I do some operation, and simply calling -release isn't  
normally a guarantee of that.


My preferred approach is to have a -close or -invalidate method that  
releases resources, breaks retain cycles, etc.. If -invalidate isn't  
called before dealloc, that's OK, but I can also call -invalidate  
explicitly if I know I want to tear down the object at a given time.


I think there are cases where the indefinite lifetime *is* what you  
want, if you have objects that can lazily fault something in from  
disk, or which encapsulate a sharable server connection, or etc. But  
those objects should be the exception, so that you can be especially  
aware of lifecycle issues in any code that deals with them. And even  
so, I usually end up having to give them an -invalidate method  
eventually, to deal with some odd situation.





I guess I do think of the delloc being called as a result of my  
release -- and that seems to be the way it is working.


The approach I'm using now is to open the file in an init method, then  
read a few 100 bytes of header in another method, then find pointers  
to read other portions of the file and read some more data, then close  
the file in the dealloc method. Lazy loading of data is an Objective - 
C/Cocoa pattern.


The alternative would be to open the file, read the entire file, and  
close it in the init method.  I guess this is the approach used by NS  
methods such as: initWithContentsOfFile, etc. However, the file could  
be megabytes in size, and so this would be considerably slower.


Another alternative would be to not use a class but just use C  
functions to do this, but that wouldn't be a Cocoa pattern at all.


Bottom line though, what are the consequences of leaving a file open?  
When does it finally get closed?


Jim Merkel___

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: dealloc and scarce resources

2011-06-29 Thread Quincey Morris
On Jun 29, 2011, at 17:43, James Merkel wrote:

 You should typically not manage scarce resources such as file descriptors, 
 network connections, and buffers or caches in a dealloc method. In 
 particular, you should not design classes so that dealloc will be invoked 
 when you think it will be invoked. Invocation of dealloc might be delayed or 
 sidestepped, either because of a bug or because of application tear-down.
 Instead, if you have a class whose instances manage scarce resources, you 
 should design your application such that you know when you no longer need the 
 resources and can then tell the instance to “clean up” at that point. You 
 would typically then release the instance, and dealloc would follow, but you 
 will not suffer additional problems if it does not.
 
 In my code I close a file in the dealloc method -- so I guess that's a file 
 descriptor. I opened the file in the init method, so it seemed logical to 
 close it in the dealloc method.

It's only logical to close the file descriptor in dealloc if it's not a scarce 
resource. The word scarce is vital to this question.

Here's a simple (though contrived) example. Suppose you have a loop that's 
compressing image files. In each iteration of the loop, you open one file for 
reading and create a new file from it. Let's suppose you've invented objects to 
represent the source and destination files, and each of these object contains a 
file descriptor for its open file. It's not hard to imagine, for example, that 
for unrelated reasons your file-reading object ends up in the autorelease pool. 
Thus, these objects will build up till the loop exits.

If you free the file descriptor in dealloc, and you have to convert 100,000 
files, you're going to need 100,000 file descriptors, because you can't recycle 
file descriptors because dealloc isn't being called until the end of the whole 
operation. That obviously isn't going to work, since the kernel can create only 
a very limited number of simultaneous file descriptors.

In this case, the recommended solution is to give your object a 
'releaseResources' method that will free up its file descriptor. This is the 
scenario that the above warning is talking about. Note that if scarcity isn't 
an issue, if there could be as many simultaneous file descriptors as you choose 
to create, then this pattern isn't necessary***.

In real life applications, causes of deferral of dealloc can be really hard to 
figure out deterministically. Thus it can be hard to know whether you *need* a 
'releaseResources' pattern or not. That's why the recommendation is couched in 
terms of such general applicability. [What the warning doesn't say, though, is 
that the opposite problem exists too. It can be *very* hard to determine when 
to call 'releaseResources', a problem which carries over into the GC world too.]

 Also, not to be facetious, if I have a bug in my code, wouldn't I fix it?

I think it's referring to the kind of bug where the object is lifetime is 
extended by an inscrutable chain of dependencies. If your design uses an 
implicit release-resource-on-dealloc pattern, it can be very hard to work out 
where to intervene, so the bug may be for all intents and purposes unfixable.

 Granted, at application tear-down, if the file is still open, it won't be 
 closed because dealloc won't be called. But again that comes under the 
 heading of a bug in the code. So I don't understand this injunction.

Actually, at application tear-down, things like file descriptors are 
irrelevant, because they're destroyed automatically with your process. However, 
there are things with more global visibility, such as a system-wide cache, or a 
network login, that destruction of your process may leak. So, application 
tear-down tends to be the site of fewer problems, but resource management is 
still something that needs to be thought through.



***Actually, it may be necessary even then. *Your* application might not care 
if the file descriptors aren't freed until much later, but you might also be 
preventing other applications from gaining exclusive access to the files for 
some other purpose, so you'll lock out such applications possibly for hours. 
This is still a case of scarcity, just a different kind of scarcity.


___

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: dealloc and scarce resources

2011-06-29 Thread James Merkel


On Jun 29, 2011, at 9:47 PM, Quincey Morris wrote:


On Jun 29, 2011, at 17:43, James Merkel wrote:

You should typically not manage scarce resources such as file  
descriptors, network connections, and buffers or caches in a  
dealloc method. In particular, you should not design classes so  
that dealloc will be invoked when you think it will be invoked.  
Invocation of dealloc might be delayed or sidestepped, either  
because of a bug or because of application tear-down.
Instead, if you have a class whose instances manage scarce  
resources, you should design your application such that you know  
when you no longer need the resources and can then tell the  
instance to “clean up” at that point. You would typically then  
release the instance, and dealloc would follow, but you will not  
suffer additional problems if it does not.


In my code I close a file in the dealloc method -- so I guess  
that's a file descriptor. I opened the file in the init method, so  
it seemed logical to close it in the dealloc method.


It's only logical to close the file descriptor in dealloc if it's  
not a scarce resource. The word scarce is vital to this question.


Here's a simple (though contrived) example. Suppose you have a loop  
that's compressing image files. In each iteration of the loop, you  
open one file for reading and create a new file from it. Let's  
suppose you've invented objects to represent the source and  
destination files, and each of these object contains a file  
descriptor for its open file. It's not hard to imagine, for example,  
that for unrelated reasons your file-reading object ends up in the  
autorelease pool. Thus, these objects will build up till the loop  
exits.


If you free the file descriptor in dealloc, and you have to convert  
100,000 files, you're going to need 100,000 file descriptors,  
because you can't recycle file descriptors because dealloc isn't  
being called until the end of the whole operation. That obviously  
isn't going to work, since the kernel can create only a very limited  
number of simultaneous file descriptors.


In this case, the recommended solution is to give your object a  
'releaseResources' method that will free up its file descriptor.  
This is the scenario that the above warning is talking about. Note  
that if scarcity isn't an issue, if there could be as many  
simultaneous file descriptors as you choose to create, then this  
pattern isn't necessary***.


In real life applications, causes of deferral of dealloc can be  
really hard to figure out deterministically. Thus it can be hard to  
know whether you *need* a 'releaseResources' pattern or not. That's  
why the recommendation is couched in terms of such general  
applicability. [What the warning doesn't say, though, is that the  
opposite problem exists too. It can be *very* hard to determine when  
to call 'releaseResources', a problem which carries over into the GC  
world too.]


Also, not to be facetious, if I have a bug in my code, wouldn't I  
fix it?


I think it's referring to the kind of bug where the object is  
lifetime is extended by an inscrutable chain of dependencies. If  
your design uses an implicit release-resource-on-dealloc pattern, it  
can be very hard to work out where to intervene, so the bug may be  
for all intents and purposes unfixable.


Granted, at application tear-down, if the file is still open, it  
won't be closed because dealloc won't be called. But again that  
comes under the heading of a bug in the code. So I don't understand  
this injunction.


Actually, at application tear-down, things like file descriptors are  
irrelevant, because they're destroyed automatically with your  
process. However, there are things with more global visibility, such  
as a system-wide cache, or a network login, that destruction of your  
process may leak. So, application tear-down tends to be the site  
of fewer problems, but resource management is still something that  
needs to be thought through.




***Actually, it may be necessary even then. *Your* application might  
not care if the file descriptors aren't freed until much later, but  
you might also be preventing other applications from gaining  
exclusive access to the files for some other purpose, so you'll lock  
out such applications possibly for hours. This is still a case of  
scarcity, just a different kind of scarcity.



Ok, thanks. For what I'm doing file descriptors are not a scarce  
resource. Also, I didn't know file descriptors are destroyed at  
application tear-down.


___

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


NSUndoManager - unstable state

2011-06-29 Thread livinginlosangeles
Is there a way to check if the NSUndomanager is in an unstable state and reset 
it?
___

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