While profiling my app with Instruments, I found a leak with an array that I allocated. To my knowledge I was doing this correctly, but it looks like something is wrong.
Let's say I have three classes, class M, A and B.
Subclass B has a unique NSArray property that is not a part of it's super class A.
M allocates and instance of subclass B.
In class M, the instance of subclass B is accessed, and the NSArray property is accessed from that class and allocated.
In subclass B, dealloc is overridden and has a release for the NSArray, and super dealloc is under it.
When I release class M, I get a leak for the NSArray object.
My understanding was that I was able to allocate the NSArray object from class M, for example:
tempClassB.myNSArray = [[NSArray alloc] initWithArray:finalArray];
And that I can override dealloc in subclass B to release it's own object that does not exist in it's super class, A. I than can call super dealloc to call dealloc in class A:
- (void) dealloc{
[myNSArray release];
[super dealloc];
}
The problem I'm having is allocating class B in class M will make class M responsible for releasing it. I should allocate the object in class B and release like I am, or put a release in class M's dealloc for the object.
Related
Why does ctor calls itself and shouldn't this make it loop? I can't quite understand what's going on.
I have looked around online but still can't find an answer.
.method family hidebysig specialname rtspecialname instance void .ctor()
{
.maxstack 8
ldarg.0
ldstr asc_203C // ""
stfld string KGER.BaseConfiguration::_get
ldarg.0
**call instance void [mscorlib]System.Object::.ctor()**
nop
ret
}
Your constructor is chaining (calling) the constructor of your base class (which is System.Object).
Even though you do not call it in trivial cases (e.g. empty constructor), the compiler will emit the call as every "part" of your object must be properly constructed.
I'm analyzing a heap dump with Eclipse Memory Analyzer (MAT).
I have a line in Heap Histogram, where Objects and Shallow Heap are 0 but there is a big amount of Retained Heap.
What does it mean? Is it not assigned to an object instance but it's only a static content? Or is it a bug in MAT?
AuthPolicy is an abstract class. As a result, there are no instances of that class. However, AuthPolicy does have some static fields source code of AuthPolicy. It does have a HashMap and ArrayList, The retained space is probably stuck in there:
...
public abstract class AuthPolicy {
private static final HashMap SCHEMES = new HashMap();
private static final ArrayList SCHEME_LIST = new ArrayList();
...
I'm using #CompileStatic for the first time, and confused as to how Groovy's map constructors work in this situation.
#CompileStatic
class SomeClass {
Long id
String name
public static void main(String[] args) {
Map map = new HashMap()
map.put("id", 123L)
map.put("name", "test file")
SomeClass someClass1 = new SomeClass(map) // Does not work
SomeClass someClass2 = map as SomeClass // Works
}
}
Given the code above I see the following error when trying to compile
Groovyc: Target constructor for constructor call expression hasn't been set
If #CompileStatic is removed, both constructors work properly.
Can anyone explain why new SomeClass(map) does not compile with #CompileStatic? And a possible addition, why does map as SomeClass still work?
Groovy actually does not give you a "Map-Constructor". The constructors
in your class are what you write down. If there are none (like in your case),
then there is the default c'tor.
But what happens, if you use the so called map c'tor (or rather call it
"object construction by map")? The general approach of groovy is like this:
create a new object using the default c'tor (this is the reason, why the
construction-by-map no longer works, if there would be just e.g.
SomeClass(Long id, String name))
then use the passed down map and apply all values to the properties.
If you disassmble your code (with #CompileDynamic (the default)) you see, that
the construction is handled by CallSite.callConstructor(Object,Object),
which boils down to this this code area.
Now bring in the version of this construction by map, that is more familiar
for the regular groovyist:
SomeClass someClass3 = new SomeClass(id: 42L, name: "Douglas").
With the dynamic version of the code, the disassembly of this looks actually
alot like your code with the map. Groovy creates a map from the param(s) and
sends it off to callConstructor - so this is actually the same code path
taken (minus the implicit map creation).
For now ignore the "cast-case", as it is actually the same for both static and
dynamic: it will be sent to ScriptBytecodeAdapter.asType which basically
gives you the dynamic behaviour in any case.
Now the #CompileStatic case: As you have witnessed, your call with an
explicit map for the c'tor no longer works. This is due to the fact, that
there never was an explicit "map-c'tor" in the first place. The class still
only has its default c'tor and with static compilation groovyc now can just
work with the things that are there (or not if there aren't in this case).
What about new SomeClass(id: 42L, name: "Douglas") then? This still works
with static compilation! The reason for this is, that groovyc unrolls this
for you. As you can see, this simply boils down to def o = new SomeClass();
o.setId(42); o.setName('Douglas'):
new #2 // class SomeClass
dup
invokespecial #53 // Method "<init>":()V
astore_2
ldc2_w #54 // long 42l
dup2
lstore_3
aload_2
lload_3
invokestatic #45 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
invokevirtual #59 // Method setId:(Ljava/lang/Long;)V
aconst_null
pop
pop2
ldc #61 // String Douglas
dup
astore 5
aload_2
aload 5
invokevirtual #65 // Method setName:(Ljava/lang/String;)V
As the CompileStatic documentation says:
will actually make sure that the methods which are inferred as being
called will effectively be called at runtime. This annotation turns
the Groovy compiler into a static compiler, where all method calls are
resolved at compile time and the generated bytecode makes sure that
this happens
As a result, a constructor with a Map argument is searched in the static compilation to "resolve it at compile time", but it is not found and thereby there is a compilation error:
Target constructor for constructor call expression hasn't been set
Adding such a constructor solves the issue with the #CompileStatic annotation, since it is resolved at compile time:
import groovy.transform.CompileStatic
#CompileStatic
class SomeClass {
Long id
String name
SomeClass(Map m) {
id = m.id as Long
name = m.name as String
}
public static void main(String[] args) {
Map map = new HashMap()
map.put("id", 123L)
map.put("name", "test file")
SomeClass someClass1 = new SomeClass(map) // Now it works also
SomeClass someClass2 = map as SomeClass // Works
}
}
You can check StaticCompilationVisitor if you want to dig deeper.
Regarding the line
SomeClass someClass2 = map as SomeClass
You are using there the asType() method of Groovy's GDK java.util.Map, so it is therefore solved at runtime even in static compilation:
Coerces this map to the given type, using the map's keys as the public
method names, and values as the implementation. Typically the value
would be a closure which behaves like the method implementation.
I make a category like this:
#interface NSObject (defaultSelector)
+(NSString *) defaultSelector;
-(NSString *)defaultSelector;
#end
Then, I used it like this:
-(void)prefetchShortcutWithTable: (Class) someNSManagedObjectClass forInputArray: (NSArray *) inputArray withDictCache: (NSMutableDictionary *) dictToSave
{
NSString * attribute = [someNSManagedObjectClass defaultSelector];
[self prefetchShortcutWithTable:NSStringFromClass(someNSManagedObjectClass) forAttribute:attribute forInputArray:inputArray withDictCache:dictToSave];
}
The whole thing works. However, how does the compiler knows that someNSManagedObjectClass will be a subclass of an NSObject?
In fact, how do I rewrite the function so that -(void)prefetchShortcutWithTable: (Class) someNSManagedObjectClass forInputArray: (NSArray *) inputArray withDictCache: (NSMutableDictionary *) dictToSave only accept subclasses of NSManagedObject?
NSObject is the base class of any someNSManagedObjectClass or anyOtherClass you are going to make.
Okay so I have three classes, ClassOne, ClassTwo, and ClassThree.
ClassOne is ran in the Main Thread, ClassTwo is ran in Thread ThreadTwo, and ClassThree is ran in ThreadThree.
In ClassTwo and in ClassThree I make calls to ClassOne and vice-versa.
ClassTwo::SomeMethod(){
int l_SomeVar = m_ClassOnePointer->SomeAccessorMethod() // return m_SomeVariable
int l_SomeVar = m_ClassOnePointer->SomeConstAccessor() // SomeConstAccessor() const;
int l_SomeVar = m_ClassOnePointer->m_SomeVariable; // Just a standard public int (not const, static, or volatile).
m_ClassOnePointer->m_SetSomeVariable(30);
m_ClassOnePointer->m_SomeVariable = 30;
Currently I use accessors and const accessors, but I don't know if its safe for threading, If it isn't how would I go about safely doing this without locks.
No, it's not thread-safe. As for getters for arbitrary types without locks - I've got nuthin.. The const doesn't help - just because the getter declares it's not going to change member vars doesn't mean some other threads can't change them. Other threads may call setters, or perhaps ClassOne has an internal thread that's changing them.