• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bundle Reloading
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bundle Reloading


  • Subject: Re: Bundle Reloading
  • From: glenn andreas <email@hidden>
  • Date: Wed, 7 Dec 2005 09:18:14 -0600


On Dec 7, 2005, at 8:44 AM, Josh Ferguson wrote:

I know there has already been a lengthy thread on unloading/ reloading a
bundle. Because of certain constraints, I need to be able to update and
reload a bundle at runtime. As it currently stands, my framework
downloads an update for itself to a temp directory, moves the old bundle
to the trash, and copies the new one to the new location. The class that
I need is loaded dynamically by creating an NSBundle instance using the
path to my class, then calling [NSBundle load] and NSClassFromString. It
seems, however, that the first loading of NSBundle is cached in memory.
When I go to load the bundle again (specifying the path to the new
bundle in the old location), it's still giving me the old bundle. I know
this because when I grab the CFBundleVersion from the plist it's giving
me the old version number.



My question is this: what do I need to change in the bundle
(CFBundleIdentifier? Class name? etc.?) to ensure that when I create the
NSBundle using -[NSBundle bundleWithPath], it actually reloads it in
memory?


The core problem is that Objective-C does not support unloading - once a class, category, etc... has been loaded, that's it - you can't remove it.

What you might be able to do, however, assuming that the classes in the bundle are nice and modular, is effectively treat the new bundle as a second, completely separate, bundle (and you might need to break your classes in two to accomplish this).

The idea is that you would treat this "dynamically updated class" as a class cluster - there would be a public abstract superclass, which would then instantiate an appropriate subclass. Each subclass would probably have the version number included with it (as would the bundle identifier).

So roughly, you'd make your bundle:

com.company.product.myclass.1: (primary class "MyClass1")

@interface MyClass1 : MyClass

and then later you'd have an update that could be downloaded:

com.company.product.myclass.2: (primary class "MyClass2")

@interface MyClass2 : MyClass

Your application would have something roughly this (heavy in pseudo code due to light in coffee):

@implementation MyClass
+ (id) alloc
{
highestVersion = 0;
for each [NSBundle allBundles] {
if bundle id starts with "com.company.product.myclass" get the versionNumber
if (versionNumber > highestVersion) {
highestVersion = versionNumber
highestBundle = bundle
}
}
check with server to see if newversion(highestVersion) exists
if newer available {
download new bundle
put it where it needs to be
[newBundle load]
highestBundle = newBundle
}
return [NSClassFromString([higestBundle principleClass]) alloc];
}
@end

Obviously, some of that should probably be cached (since you don't want to contact a server for each alloc), but that basic structure should work.


Glenn Andreas email@hidden
<http://www.gandreas.com/> wicked fun!
quadrium | build, mutate, evolve | images, textures, backgrounds, art

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden
References: 
 >Bundle Reloading (From: "Josh Ferguson" <email@hidden>)

  • Prev by Date: Re: Bundle Reloading
  • Next by Date: RE: Bundle Reloading
  • Previous by thread: Re: Bundle Reloading
  • Next by thread: RE: Bundle Reloading
  • Index(es):
    • Date
    • Thread