Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

- Fixed framework install paths to use @rpath.

NSTimer-NoodleExtensions:
- Added link to blog post in comment.

NoodleGlue:
- Fixed comment which referred to older method name.
- Added properties for the main and cleanup blocks.
- Added NSObject category that allows you to specify a block to be invoked
when the object is deallocated.
  • Loading branch information...
commit 5ec8ec7b377dc3ae6ca91dd2ce2fdfd8d277e9ff 1 parent 4c14f00
@MrNoodle authored
View
2  NSTimer-NoodleExtensions.h
@@ -40,6 +40,8 @@ typedef void (^NoodleTimerBlock)(NSTimer *timer);
Note that calling -setFireTime: may not work properly on this timer. A new timer should be created if you wish to have
it fire at a different time after initial creation.
+
+ For more details, check out the related blog post at http://www.noodlesoft.com/blog/2010/07/01/playing-with-nstimer/
*/
+ (NSTimer *)scheduledTimerWithAbsoluteFireDate:(NSDate *)fireDate target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo;
+ (NSTimer *)scheduledTimerWithAbsoluteFireDate:(NSDate *)fireDate block:(NoodleTimerBlock)block;
View
30 NoodleGlue.h
@@ -48,6 +48,7 @@ typedef void (^NoodleGlueCleanupBlock)(NoodleGlue *glue);
observer, you need to retain it somewhere because the notification center won't (or if using GC, keep a strong
reference somewhere).
+ For more details, check out the related blog post at http://www.noodlesoft.com/blog/2010/07/01/playing-with-nstimer/
*/
@interface NoodleGlue : NSObject
{
@@ -55,11 +56,14 @@ typedef void (^NoodleGlueCleanupBlock)(NoodleGlue *glue);
NoodleGlueCleanupBlock _cleanupBlock;
}
+@property (readwrite, copy) NoodleGlueBlock glueBlock;
+@property (readwrite, copy) NoodleGlueCleanupBlock cleanupBlock;
+
+ (NoodleGlue *)glueWithBlock:(NoodleGlueBlock)glueBlock;
+ (NoodleGlue *)glueWithBlock:(NoodleGlueBlock)glueBlock cleanupBlock:(NoodleGlueCleanupBlock)cleanupBlock;
-// Initializes a glue object. glueBlock will be invoked when this object's -fire: method is called with the argument
-// to -fire: passed on as a parameter. cleanupBlock is invoked when this object is dealloc'ed/finalized with the
+// Initializes a glue object. glueBlock will be invoked when this object's -invoke: method is called with the argument
+// to -invoke: passed on as a parameter. cleanupBlock is invoked when this object is dealloc'ed/finalized with the
// glue object being dealloc'ed sent in as a parameter.
- (id)initWithBlock:(NoodleGlueBlock)glueBlock cleanupBlock:(NoodleGlueCleanupBlock)cleanupBlock;
@@ -68,4 +72,26 @@ typedef void (^NoodleGlueCleanupBlock)(NoodleGlue *glue);
@end
+/*
+ NSObject category which, through the use of NoodleGlue and associative references, allows you to assign a block
+ to be invoked when the object is deallocated.
+
+ This code is more proof of concept than anything you'd want to use in production. For one, it's not threadsafe.
+
+ For more details, check out the related blog post at http://www.noodlesoft.com/blog/2010/07/05/fun-with-glue/
+ */
+@interface NSObject (NoodleCleanupGlue)
+
+// Sets a block to be invoked when the object is deallocated/collected. Will return an identifier that you can
+// use to remove the block later. Note that you need to retain this identifier if you intend to use it later.
+// Also, treat the identifier as an opaque object. Its actual type/formatting/structure may change in future
+// versions.
+- (id)addCleanupBlock:(void (^)(id object))block;
+
+// Removes the cleanup block using the identifier returned from a previous call to -addCleanupBlock:
+- (void)removeCleanupBlock:(id)identifier;
+
+@end
+
+
#endif
View
67 NoodleGlue.m
@@ -24,12 +24,16 @@
// THE SOFTWARE.
#import "NoodleGlue.h"
+#import <objc/runtime.h>
#if defined(NS_BLOCKS_AVAILABLE) && (NS_BLOCKS_AVAILABLE == 1)
@implementation NoodleGlue
+@synthesize glueBlock = _glueBlock;
+@synthesize cleanupBlock = _cleanupBlock;
+
+ (NoodleGlue *)glueWithBlock:(NoodleGlueBlock)glueBlock
{
return [self glueWithBlock:glueBlock cleanupBlock:nil];
@@ -78,7 +82,70 @@ - (void)invoke:(id)object
_glueBlock(self, object);
}
+@end
+
+
+@implementation NSObject (NoodleCleanupGlue)
+
+static char cleanupGlueKey;
+
+- (id)addCleanupBlock:(void (^)(id object))block
+{
+ NSMutableDictionary *glueTable;
+ NoodleGlue *glue;
+ __block __weak id blockSelf;
+ id key;
+
+ blockSelf = self;
+ glue = [[NoodleGlue alloc] initWithBlock:nil
+ cleanupBlock:
+ ^(NoodleGlue *glue)
+ {
+ block(blockSelf);
+ }];
+
+
+ glueTable = objc_getAssociatedObject(self, &cleanupGlueKey);
+
+ if (glueTable == nil)
+ {
+ glueTable = [NSMutableDictionary dictionary];
+ objc_setAssociatedObject(self, &cleanupGlueKey, glueTable, OBJC_ASSOCIATION_RETAIN);
+ }
+
+ key = [NSString stringWithFormat:@"%p", glue];
+ [glueTable setObject:glue forKey:key];
+
+ [glue release];
+
+ return key;
+}
+
+- (void)removeCleanupBlock:(id)identifier
+{
+ NSMutableDictionary *glueTable;
+
+ glueTable = objc_getAssociatedObject(self, &cleanupGlueKey);
+
+ if (glueTable != nil)
+ {
+ NoodleGlue *glue;
+
+ glue = [glueTable objectForKey:identifier];
+
+ // Clear the cleanup block since we don't want it to be invoked when it gets released when it's removed
+ // from the table
+ [glue setCleanupBlock:nil];
+ [glueTable removeObjectForKey:identifier];
+
+ if ([glueTable count] == 0)
+ {
+ objc_setAssociatedObject(self, &cleanupGlueKey, nil, OBJC_ASSOCIATION_RETAIN);
+ }
+ }
+}
@end
+
#endif
View
7 NoodleKit.xcodeproj/project.pbxproj
@@ -959,7 +959,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = NoodleKit_Prefix.pch;
INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "@executable_path/../Frameworks";
+ INSTALL_PATH = "@rpath";
PRODUCT_NAME = NoodleKit;
WRAPPER_EXTENSION = framework;
};
@@ -977,7 +977,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = NoodleKit_Prefix.pch;
INFOPLIST_FILE = Info.plist;
- INSTALL_PATH = "@executable_path/../Frameworks";
+ INSTALL_PATH = "@rpath";
PRODUCT_NAME = NoodleKit;
WRAPPER_EXTENSION = framework;
};
@@ -992,7 +992,7 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks/ @loader_path/Frameworks/";
+ LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.5;
ONLY_ACTIVE_ARCH = YES;
"OTHER_CFLAGS[arch=i386]" = (
@@ -1017,6 +1017,7 @@
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.5;
"OTHER_CFLAGS[arch=i386]" = (
"$(inherited)",
Please sign in to comment.
Something went wrong with that request. Please try again.