diff --git a/rococoa/rococoa-core/src/main/java/org/rococoa/Rococoa.java b/rococoa/rococoa-core/src/main/java/org/rococoa/Rococoa.java index 861c5e6..e7281b9 100644 --- a/rococoa/rococoa-core/src/main/java/org/rococoa/Rococoa.java +++ b/rococoa/rococoa-core/src/main/java/org/rococoa/Rococoa.java @@ -19,6 +19,7 @@ package org.rococoa; +import java.lang.reflect.Method; import java.lang.reflect.Proxy; import net.bytebuddy.ByteBuddy; @@ -53,13 +54,17 @@ public abstract class Rococoa { public static T createClass(String ocClassName, Class type) { return wrap(Foundation.getClass(ocClassName), type, false); } - + /** * Create a Java NSObject representing an instance of the Objective-C class * ocClassName. The Objective-C instance is created by calling the static * factory method named ocMethodName, passing args. */ public static T create(String ocClassName, Class javaClass, String ocMethodName, Object... args) { + return create(ocClassName, javaClass, null, ocMethodName, args); + } + + public static T create(String ocClassName, Class javaClass, Method method, String ocMethodName, Object... args) { boolean weOwnObject = Foundation.selectorNameMeansWeOwnReturnedObject(ocMethodName); // If we don't own the object we know that it has been autorelease'd @@ -68,7 +73,7 @@ public static T create(String ocClassName, Class javaC // Objects that we own (because they were created with 'alloc' or 'new') // have not been autorelease'd, so we don't retain them. boolean retain = !weOwnObject; - return create(ocClassName, javaClass, ocMethodName, retain, args); + return create(ocClassName, javaClass, method, ocMethodName, retain, args); } /** @@ -79,8 +84,8 @@ public static T create(String ocClassName, Class javaC return create(ocClassName, javaClass, "new"); } - private static T create(String ocClassName, Class javaClass, - String ocFactoryName, + private static T create(String ocClassName, Class javaClass, Method method, + String ocFactoryName, boolean retain, Object... args) { if (logging.isLoggable(Level.FINEST)) { @@ -88,7 +93,7 @@ private static T create(String ocClassName, Class java ocClassName, javaClass.getName(), ocFactoryName, new VarArgsUnpacker(args))); } ID ocClass = Foundation.getClass(ocClassName); - ID ocInstance = Foundation.send(ocClass, ocFactoryName, ID.class, args); + ID ocInstance = Foundation.send(ocClass, ocFactoryName, ID.class, method, args); CFIndex initialRetainCount = Foundation.cfGetRetainCount(ocInstance); T result = wrap(ocInstance, javaClass, retain); checkRetainCount(ocInstance, retain ? initialRetainCount.intValue() + 1 : initialRetainCount.intValue()); diff --git a/rococoa/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSArray.java b/rococoa/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSArray.java index f61fbed..d58f80a 100755 --- a/rococoa/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSArray.java +++ b/rococoa/rococoa-core/src/main/java/org/rococoa/cocoa/foundation/NSArray.java @@ -26,6 +26,7 @@ public abstract class NSArray extends NSObject { public static final _Class CLASS = Rococoa.createClass("NSArray", _Class.class); //$NON-NLS-1$ public interface _Class extends ObjCClass { + NSArray arrayWithObject(NSObject anObject); /** * @param objects Contents and then a trailing null */ diff --git a/rococoa/rococoa-core/src/test/java/org/rococoa/RococoaObjectOwnershipTest.java b/rococoa/rococoa-core/src/test/java/org/rococoa/RococoaObjectOwnershipTest.java index 8a672d0..2f4258d 100644 --- a/rococoa/rococoa-core/src/test/java/org/rococoa/RococoaObjectOwnershipTest.java +++ b/rococoa/rococoa-core/src/test/java/org/rococoa/RococoaObjectOwnershipTest.java @@ -19,7 +19,6 @@ package org.rococoa; -import org.junit.Ignore; import org.junit.Test; import org.rococoa.cocoa.foundation.*; import org.rococoa.test.RococoaTestCase; @@ -34,17 +33,26 @@ public class RococoaObjectOwnershipTest extends RococoaTestCase { public static boolean shouldNotBeInPool = false; @Test - public void directFactoryMethodsReturnsYieldsPooledObject() { + public void directFactoryMethodsReturnsYieldsPooledObject() throws Exception { check(shouldBeInPool, new Factory() { - public NSArray create() { - return Rococoa.create("NSArray", NSArray.class, "arrayWithObjects:", NSNumber.CLASS.numberWithInt(0)); + public NSArray create() throws Exception { + return Rococoa.create("NSArray", NSArray.class, + NSArray._Class.class.getMethod("arrayWithObjects", NSObject[].class), + "arrayWithObjects:", NSNumber.CLASS.numberWithInt(0)); + } + }); + check(shouldBeInPool, + new Factory() { + public NSArray create() throws Exception { + return Rococoa.create("NSArray", NSArray.class, + "arrayWithObject:", NSNumber.CLASS.numberWithInt(0)); } }); } @Test - public void factoryMethodOnClassYieldsPooledObject() { + public void factoryMethodOnClassYieldsPooledObject() throws Exception { check(shouldBeInPool, new Factory() { public NSArray create() { @@ -54,8 +62,7 @@ public NSArray create() { } @Test - @Ignore - public void createYieldsNonPooledObject() { + public void createYieldsNonPooledObject() throws Exception { check(shouldNotBeInPool, new Factory() { public NSDate create() { @@ -65,8 +72,7 @@ public NSDate create() { } @Test - @Ignore - public void newYieldsNonPooledObject() { + public void newYieldsNonPooledObject() throws Exception { // calling new on an NSClass results in a NOT autorelease'd object check(shouldNotBeInPool, new Factory() { @@ -77,7 +83,7 @@ public NSArray create() { } @Test - public void allocYieldsNonPooledObject() { + public void allocYieldsNonPooledObject() throws Exception { // calling alloc on an NSClass results in a NOT autorelease'd object check(shouldNotBeInPool, new Factory() { @@ -89,10 +95,10 @@ public NSObject create() { } private interface Factory { - NSObject create(); + NSObject create() throws Exception; } - private void check(boolean expectedAutorelease, Factory factory) { + private void check(boolean expectedAutorelease, Factory factory) throws Exception { int expectedInitialRetainCount = expectedAutorelease ? 2 : 1; // that will decrease the count IF it was pooled int expectedFinalRetainCount = expectedAutorelease ?