Permalink
Browse files

Added @unsafeify(), like @weakify() but with __unsafe_unretained

  • Loading branch information...
jspahrsummers committed Sep 6, 2012
1 parent 0e79693 commit 1d863a0a309b5605fa1b0ce751a17279db2bde58
Showing with 42 additions and 21 deletions.
  1. +1 −1 README.md
  2. +30 −17 Tests/EXTScopeTest.m
  3. +11 −3 extobjc/EXTScope.h
View
@@ -12,7 +12,7 @@ libextobjc currently includes the following features:
* **Concrete protocols**, using EXTConcreteProtocol, for providing default implementations of the methods in a protocol.
* **Simpler and safer key paths**, using EXTKeyPathCoding, which automatically checks key paths at compile-time.
* **Compile-time checking of selectors** to ensure that an object declares a given selector, using EXTSelectorChecking.
- * **Easier use of weak variables in blocks**, using `@weakify` and `@strongify` in the EXTScope module.
+ * **Easier use of weak variables in blocks**, using `@weakify`, `@unsafeify`, and `@strongify` from the EXTScope module.
* **Safer private methods**, using EXTPrivateMethod, for declaring methods on a class, and getting notified if they conflict with other existing methods.
* **Scope-based resource cleanup**, using `@onExit` in the EXTScope module, for automatically cleaning up manually-allocated memory, file handles, locks, etc., at the end of a scope.
* **EXTNil, which is like `NSNull`, but behaves much more closely to actual `nil`** (i.e., doesn't crash when sent unrecognized messages).
View
@@ -157,30 +157,43 @@ - (void)testExceptionCleanup {
STAssertEqualObjects(str, @"foobar", @"'bar' should've been appended to 'foo' at the end of a called method that threw an exception");
}
-- (void)testWeakifyStrongify {
- NSString *foo = @"foo";
- NSString *bar = @"bar";
+- (void)testWeakifyUnsafeifyStrongify {
+ void (^verifyMemoryManagement)(void);
- void *fooPtr = &foo;
- void *barPtr = &bar;
+ @autoreleasepool {
+ NSString *foo __attribute__((objc_precise_lifetime)) = [@"foo" mutableCopy];
+ NSString *bar __attribute__((objc_precise_lifetime)) = [@"bar" mutableCopy];
- @weakify(foo, bar);
+ void *fooPtr = &foo;
+ void *barPtr = &bar;
- BOOL (^matchesFooOrBar)(NSString *) = ^ BOOL (NSString *str){
- @strongify(bar, foo);
+ @weakify(foo);
+ @unsafeify(bar);
- STAssertEqualObjects(foo, @"foo", @"");
- STAssertEqualObjects(bar, @"bar", @"");
+ BOOL (^matchesFooOrBar)(NSString *) = ^ BOOL (NSString *str){
+ @strongify(bar, foo);
- STAssertTrue(fooPtr != &foo, @"Address of 'foo' within block should be different from its address outside the block");
- STAssertTrue(barPtr != &bar, @"Address of 'bar' within block should be different from its address outside the block");
+ STAssertEqualObjects(foo, @"foo", @"");
+ STAssertEqualObjects(bar, @"bar", @"");
- return [foo isEqual:str] || [bar isEqual:str];
- };
+ STAssertTrue(fooPtr != &foo, @"Address of 'foo' within block should be different from its address outside the block");
+ STAssertTrue(barPtr != &bar, @"Address of 'bar' within block should be different from its address outside the block");
+
+ return [foo isEqual:str] || [bar isEqual:str];
+ };
+
+ STAssertTrue(matchesFooOrBar(@"foo"), @"");
+ STAssertTrue(matchesFooOrBar(@"bar"), @"");
+ STAssertFalse(matchesFooOrBar(@"buzz"), @"");
+
+ verifyMemoryManagement = [^{
+ // Can only strongify the weak reference without issue.
+ @strongify(foo);
+ STAssertNil(foo, @"");
+ } copy];
+ }
- STAssertTrue(matchesFooOrBar(@"foo"), @"");
- STAssertTrue(matchesFooOrBar(@"bar"), @"");
- STAssertFalse(matchesFooOrBar(@"buzz"), @"");
+ verifyMemoryManagement();
}
@end
View
@@ -44,7 +44,15 @@
*/
#define weakify(...) \
try {} @finally {} \
- metamacro_foreach(ext_weakify_,, __VA_ARGS__)
+ metamacro_foreach_cxt(ext_weakify_,, __weak, __VA_ARGS__)
+
+/**
+ * Like #weakify, but uses \c __unsafe_unretained instead, for targets or
+ * classes that do not support weak references.
+ */
+#define unsafeify(...) \
+ try {} @finally {} \
+ metamacro_foreach_cxt(ext_weakify_,, __unsafe_unretained, __VA_ARGS__)
/**
* Strongly references each of the variables provided as arguments, which must
@@ -81,8 +89,8 @@ typedef void (^ext_cleanupBlock_t)();
void ext_executeCleanupBlock (__strong ext_cleanupBlock_t *block);
-#define ext_weakify_(INDEX, VAR) \
- __weak __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
+#define ext_weakify_(INDEX, CONTEXT, VAR) \
+ CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
#define ext_strongify_(INDEX, VAR) \
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);

0 comments on commit 1d863a0

Please sign in to comment.