problem with applying md5 to data
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
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
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
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
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
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
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
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
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
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
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)
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
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?
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
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
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
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
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?
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?
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
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)
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?
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
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)
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)
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
• 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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?
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
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?
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
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
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
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
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
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