Ipphones

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Monday, 18 August 2008

Dynamically adding class objects

Posted on 12:31 by Unknown
Okay, folks, the first draft of the book is done, and I have some breathing room until the chapters start coming back from the tech reviewer and copy editor. Mostly, I'm using that time to catch up on sleep and house jobs and spend some time with the kids, but I've also been working on an idea I mentioned earlier about creating a way for NSObjects to automatically persist themselves into a SQLite database. I just finished my first draft of the code to do that, and once I've done some more thorough testing, I'll do a blog post about it.

Today, I'm going to post one of the little gotchas that bit me while writing that code, and which is really, really hard to figure out from Apple's documentation: how to dynamically add a class method at runtime. What I did in my persistence classes was to create class methods to help you retrieve objects. So, if you wanted to retrieve all the objects in the database where the name property equaled "John", you could do this


NSArray *johns = [Person findByName:@"John"];


Anybody who has worked with Ruby's excellent ActiveRecord implementation will recognize this pattern as the one used there. The way to implement this is to override resolveClassMethod: (you would use resolveInstanceMethod: to do the same thing for instance methods, but that is documented well and easy to implement so I won't discuss it here).

The resolveClassMethod: documentation refers you to resolveInstanceMethod: for an example implementation, which looks like this:


+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
if (aSEL == @selector(resolveThisMethodDynamically))
{
class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
return YES;
}
return [super resolveInstanceMethod:aSel];
}


If you use code like that in your resolveClassMethod:, however, you'll get an unrecognized selector error at runtime. Why? Because that code adds a method to the class object, which means you added an instance method to that class. That's not what you want. What you want is to add a method to your class' metaclass object instance, which means going to the runtime to get the Class object that represents the class' metaclass object (say that five times fast!). So, the example above, when turned into a class method override, would look like this:


+ (BOOL) resolveClassMethod:(SEL)aSEL
{
if (aSEL == @selector(resolveThisMethodDynamically))
{
Class selfMetaClass = objc_getMetaClass([[self className] UTF8String]);
class_addMethod([selfMetaClass, aSEL, (IMP) dynamicMethodIMP, "v@:");
return YES;
}
return [super resolveClassMethod aSEL];
}


And, in the immortal words of Bugs Bunny: Viola! You've added a class method to your class at runtime. Of course, you have to create the function dynamicMethodIMP in order for this to work and do all the other assorted steps necessary to make dynamic methods work, but this isn't a tutorial on dynamic method creation, just a solution to one gotcha you may encounter while doing it.
Email ThisBlogThis!Share to XShare to Facebook
Posted in Gotcha, iPHone, iPhone SDK, SQLite | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Strong Encryption for Cocoa / Cocoa Touch
    Please do not use this code! Instead, check out Jim Dovey's Common Crypto code from AQToolkit . AES is a strong encryption standard tha...
  • Texture Coordinate Arrays or Things Nobody Tells You
    For some reason, a lot of OpenGL stuff just isn't well documented. Yes, I read the Red Book chapter on texturing. It didn't have a s...
  • Dynamically adding class objects
    Okay, folks, the first draft of the book is done, and I have some breathing room until the chapters start coming back from the tech reviewer...
  • Web Services Fun
    Before we work more with libxml, let's talk about web services. Web services are a good practical application of XML and, it would seem ...
  • An OpenGL Project Template for Xcode
    I'm not a fan of the OpenGL ES Application project template that ships with the iPhone SDK. It's a pain in the ass to go in and dele...
  • Handling Double Taps
    Alright, since the NDA is down, let's celebrate by posting some information, shall we? One question that I see posted a lot by new iPhon...
  • Twittering iPhone Developer List
    Tim Haines, the developer of the excellent BurnBall game, has started a list of iPhone developers who use Twitter. The last time I checked,...
  • More on OpenGL and Normals
    In an earlier post I talked about surface normals in OpenGL. In writing the Wavefront OBJ loading class, I've learned far more about no...
  • OpenGL ES From the Ground Up, Part 1 Addendum: Alphabet Soup
    One problem with blog postings is that they are self-edited. For my postings here, I have no external technical review and no copy editing d...
  • Writing
    I'm pretty swamped with writing work at the moment. The book project is going pretty well, and I'm fortunate to have a very experien...

Categories

  • 3D Models
  • Ad Hoc Distribution
  • ADC
  • Address Book
  • Amazon
  • Anaglyphs
  • App Store
  • Apple
  • Apple DTS
  • Apple Store
  • Application Store
  • articles
  • Award
  • Background Processing
  • Barcodes
  • Beta
  • Blog
  • Blogger
  • Blogging
  • Blogs
  • Blogspot
  • Book project
  • Bug Reporting
  • Captain Obvious
  • Categories
  • Censorship
  • CFFoundation
  • CGAffineTransform
  • Clang Static Analyzer
  • Cocoa
  • Cocoa Touch
  • Code Reuse
  • Code Signing
  • Computer
  • conferences
  • Controller Classes
  • Core Animation
  • Daring Fireball
  • Database
  • Debugging
  • Defect
  • Delegates
  • Design Awards
  • Developer Certifications
  • Discussion Forums
  • Edit Mode
  • employment opportunities
  • Encryption
  • Enterprise
  • Errata
  • free code
  • Free software
  • Full Screen
  • Game Programming
  • Gestures
  • Getting Started
  • goof
  • Google Code
  • Google Maps
  • Gotcha
  • Help
  • HIG
  • HTTP PUT
  • Idiots
  • Idle Timer
  • Images
  • Instruments
  • Interface Builder
  • iPHone
  • iPhone Applications
  • iPhone Dev Center
  • iPhone Developers
  • iPhone OS 3.0
  • iPhone SDK
  • iPhone SDK PNG
  • iPhone Simulator
  • iPhoneSDK
  • iPod
  • Job Opportunities.
  • k
  • Key Value Observing
  • Keynote
  • KVO
  • Landscape Mode
  • Learn Cocoa
  • Learn Cocoa on the Mac
  • libxml
  • Licensing
  • Mac Developers
  • Mac OS X
  • Macworld Expo
  • Microsoft
  • NDA
  • NeHe
  • New Category
  • New Release
  • NSFileHandle
  • NSMutableArray
  • NSMutableURLRequest
  • NSXML
  • Object-Oriented Design
  • Objective-C
  • Open Source
  • OpenGL ES
  • Optimizations
  • Other blogs
  • Paired Arrays
  • Parsing
  • Particle Engine
  • Party
  • PeopleSoft
  • Performance
  • Persistence
  • Pink Screen of Death
  • Piracy
  • Pixar
  • Podcasts
  • Press Release WTF
  • Press Releases WTF
  • private APIs Google
  • Project Template
  • Properties
  • Random Numbers
  • Rant
  • Rejected
  • Resources
  • Responder Chain
  • REST
  • Reverse Engineering
  • Rumors
  • Runtime
  • Sample Code
  • Screencast
  • screenshot
  • Scroll Views
  • snippet
  • Snow Leopard.
  • SOAP
  • Sockets
  • Source
  • Splash Screen
  • SQLite
  • SQLitePersistentObjects
  • Steve Jobs
  • Steve-Note
  • Strings
  • Stupidity
  • Subversion
  • Table Views
  • Taps
  • Template
  • Tip
  • Tips
  • Tririga
  • tutorials
  • Twitter
  • UIAlertView
  • UIColor
  • UIImage
  • UIPickerView
  • UIScrollView
  • UITextField
  • UIView
  • UIWebView
  • Update
  • Utilities
  • UUID
  • Vacation
  • Version Control
  • Web Services
  • Writing
  • WTF
  • WWDC
  • Xcode
  • XML

Blog Archive

  • ►  2009 (141)
    • ►  May (14)
    • ►  April (30)
    • ►  March (48)
    • ►  February (26)
    • ►  January (23)
  • ▼  2008 (163)
    • ►  December (46)
    • ►  November (25)
    • ►  October (44)
    • ►  September (2)
    • ▼  August (5)
      • Wh00t!
      • SQLitePersistentObjects now in Google Code Repository
      • SQLite Persistent Objects
      • Dynamically adding class objects
      • Book's Almost Done
    • ►  July (2)
    • ►  June (9)
    • ►  May (2)
    • ►  April (11)
    • ►  March (17)
Powered by Blogger.

About Me

Unknown
View my complete profile