I have an NSMutableArray called message that I've alloc'd in init and release in dealloc. I can usually use a string in a CCCallFuncND action without a problem, even if it's an index of an array, such as:
displayMessagePiece = [CCCallFuncND actionWithTarget:self selector:#selector(displayMessageBoxString : data:) data:[[NSString stringWithFormat:[labelPieces objectAtIndex:i]] retain]];
However, if I use my mutable string, I get a crash with a green arrow pointing to my line of code that I have it in, and it says "EXC_BAD_ACCESS" with some hexadecimal.
Here's my action and sequence where I'm trying to use NSMutableString:
id displayMessage = [CCCallFuncND actionWithTarget:self selector:#selector(displayMessageBoxString : data:) data:[[NSString stringWithFormat:[message copy]] retain]];
[self runAction:[CCSequence actions:displayMessage,nil]];
Notice I use [message copy], although I've tried also just message.
I smell bad practice:
NSString* s = [[NSString stringWithFormat:[labelPieces objectAtIndex:i]] retain];
[CCCallFuncND actionWithTarget:self
selector:#selector(displayMessageBoxString:data:)
data:s];
First of all you are retaining a string that you may or may not be releasing. There is no guarantee that the displayMessageBoxString selector ever gets called. For example, the node running the call func action may be removed from the scene before the selector is called, or you may be changing the entire scene before the selector is called. In both cases you will be leaking the string.
There's also no reason to use CCCallFuncND when there's CCCallFuncO. CCCallFuncND is particularly harmful when your project is using ARC. In that case you'd have to bridge cast the object to void*, at which point ARC might simply release the memory, rightfully assuming that non-ARC code now manages the object's memory. The same may actually be true for autorelease, but I'm not 100% certain about that.
So first order of business is to use CCCallFuncO and re-test if your problem is gone. Also rely on autorelease, do not retain the string since you will not be able to release it in all cases.
NSString* s = [NSString stringWithFormat:[labelPieces objectAtIndex:i]];
[CCCallFuncO actionWithTarget:self
selector:#selector(displayMessageBoxString:)
object:s];
Now if your minimum target is iOS 4.0, you should really be using blocks instead. This is particularly true if you need both sender and object at the same time. The block has access to the local scope, so you can use the simplest CCCallBlock action in this case:
NSString* s = [NSString stringWithFormat:[labelPieces objectAtIndex:i]];
[CCCallBlock actionWithBlock:^void(){
CCLOG(#"sender is: %#, string is: %#", self, s);
}];
Et voila, all problems solved and guaranteed not to cause any memory leaks.
Note that you can also write the block without void() like this:
[CCCallBlock actionWithBlock:^{
CCLOG(#"sender is: %#, string is: %#", self, s);
}];
Personally I find it helpful to remind myself and others about the return type and parameters, even if there are none.
Related
If I use this code, the function returns me null as the Resolve worked sometimes and failed sometimes (based on when this was called)
Platform::WeakReference wr(this);
Windows::Foundation::Collections::IAsyncOperation<Object1^>^ asyncTask =
concurrency::create_async(
[wr, timeoutMS](concurrency::cancellation_token token) -> Object1^
{
if (auto refToThis = wr.Resolve<CurrentClass>())
{
// Do something
}
else return null; // The code took this path if the call was made
// immediately, if the call was made from inner
// page or
// even after 5 sec in Main Page init – It always
// worked
}
Where as if I pass this reference in lambda expression it always resolves
Platform::WeakReference wr(this);
Windows::Foundation::Collections::IAsyncOperation<Object1^>^ asyncTask =
concurrency::create_async(
[this, wr, timeoutMS](concurrency::cancellation_token token) -> Object1^
{
if (auto refToThis = wr.Resolve<CurrentClass>())
{
// Do something - It resolves always now
}
else return null;
}
Any clue why this happens? I am new to C++/Cx, I read that its not good to pass this ref in lambda expressions, but the resolve fails if I dont pass
Why the second example always work:
You are capturing this in the lambda closure [], means you are doing a copy of this inside the lambda scope. Since this is probably a ref class it means you increment the reference counter of the pointer on it, meaning this will not be destroyed. When resolving the weak reference, since this is still alive, you are able to retrieve it from the weak reference.
In the first example, you are passing only the weak reference to the lambda closure, since you are probably working with some UI element, if this is destroyed, the weak reference resolution will return nullptr.
You should either pass a weak reference or directly this in the lambda closure, but in the case where you pass this, you should ensure that you will be called by this lambda in order to avoid keeping a reference on an object causing it to never be deleted, creating a memory leak.
I am setting up a block which gets called on a custom UIButton press. I am assigning the block to the UIButton instance in viewDidLoad().
- (void) viewDidLoad{
[super viewDidLoad];
_customBTN.block = ^{
self.test = #"Something";
}
}
Should I keep the block on the stack since the block can only get called on a button press and that means viewDidLoad() would be on the stack, and this can be considered performant/best practice ... or am I doing something wrong?
Blocks don't stay on stacks (memory stack) and rather are copied (Objc objects referred inside block get a retain call (+1 retainCount) and scalar variables get copied) to heap when instantiated. It means when the line:
_customBTN.block = ^{
self.test = #"Something";
};
is executed, stack frame created for viewDidLoad function got popped from the stack, self got a +1 retainCount and block was assigned to the block property of _customBTN, later on when _customBTN calls the block (on say button tapped event) the block is executed and it uses self and does what it does.
P.S. Its safe to use weak references to self when referring inside a block. weak wouldn't increase retainCount of self (which can lead to a retain cycles in worse cases).
You can do it like this if there is no other choice. Also, do not use self in block. Create a week reference like this:
__weak typeof(self) weakSelf = self;
And use it in blocks:
_customBTN.block = ^{
weakSelf.test = #"Something";
}
I have a Swift project that's using AVCaptureSession to take photos within the app. I'm having difficulty getting the right syntax to properly clean up my objects. In Obj-C the suggested code would be as follows;
// Releases the object - used for late session cleanup
static void capture_cleanup(void* p)
{
NewPostPreviewViewController* csc = (NewPostPreviewViewController*)p;
[csc release]; // releases capture session if dealloc is called
}
// Stops the capture - this stops the capture, and upon stopping completion releases self.
- (void)stopCapture {
// Retain self, it will be released in capture_cleanup. This is to ensure cleanup is done properly,
// without the object being released in the middle of it.
[self retain];
// Stop the session
[session stopRunning];
// Add cleanup code when dispatch queue end
dispatch_queue_t queue = dispatch_queue_create("VideoDataOutputQueue", NULL);
dispatch_set_context(queue, self);
dispatch_set_finalizer_f(queue, capture_cleanup);
[dataOutput setSampleBufferDelegate: self queue: queue];
dispatch_release(queue);
}
The finalizer would call capture_cleanup but I have no idea how to set the context or the pointer to the capture_cleanup function (or even what the function definition would look like)
So far I've tried the following but I'm not convinced I'm even on the right track;
let p: UnsafeMutablePointer<NewPostPreviewViewController> = UnsafeMutablePointer.alloc(sizeof(NewPostPreviewViewController))
p.initialize(self)
var videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", nil)
dispatch_set_context(videoDataOutputQueue, p)
dispatch_set_finalizer_f(videoDataOutputQueue, ????);
self.videoDataOutput!.setSampleBufferDelegate(self, queue: videoDataOutputQueue)
dispatch_release(videoDataOutputQueue)
Any help converting this would be most appreciated!
Solved using bridging to Objective-C code. By including a CameraController.m Objective-C class in my Swift project (with associated header) I bridge for access to the camera feed.
The Objective-C class does all the work I need, and stores the last image taken. It also produces a notification once the image is taken, allowing my Swift class to observe the notification and go get the last image taken.
I've been trying to track down memory leaks in our application, and keep finding myself back looking at Spark components as the culprit.
I think I've found the cause, but my understanding of Garbage Collection / mark & sweep is not too hot, so I'd like to verify my findings.
Many classes in Spark use RichEditableText for displaying their text properties (ComboBox,TextInput).
RichEditableText has a local textContainerManager property, and frequently calls compose() on this.
Here's the relevant abridged extract from TextContainerManager
// Line 282 - 292:
static private var stringFactoryDictionary:Dictionary = new Dictionary(true);
static private function inputManagerStringFactory(config:IConfiguration):StringTextLineFactory
{
var factory:StringTextLineFactory = stringFactoryDictionary[config];
if (factory == null)
{
factory = new StringTextLineFactory(config);
stringFactoryDictionary[config] = factory;
}
return factory;
}
// Line 1204:
public function compose() {
// Line 1238:
var inputManagerFactory:TextLineFactoryBase = (_sourceState == SOURCE_STRING) ? inputManagerStringFactory(_config) : _inputManagerTextFlowFactory;
// Line 1242:
inputManagerFactory.swfContext = Configuration.playerEnablesArgoFeatures ? this : _swfContext;
}
Line 1242 is the crucial line here, as it gives the static dictionary a reference to our component.
(Note - I've checked this with the debugger to confirm which branch of the ternary gets executed.) This would prevent the instance from ever being garbage collected.
Eg: Static dictionary has a value with a reference to the instance -- instance cannot be GC'd.
In turn, this would prevent any other instances which have a reference to the instance of TextContainerManager from being GC'd also.
While this theory certainly matches what I'm seeing in our app, I can't beleive that there really is a memory leak in such a low-level spark component.
Could someone please shed some light on this?
BTW - I've opened a defect on bugs.adobe.com to track this issue, should it prove to be a genuine bug:
https://bugs.adobe.com/jira/browse/SDK-29531
I've heard there are several memory problems related to TLF.
That should be corrected in the Flex 4.5 SDK.
In the meantime, you could still open a ticket on http://bugs.adobe.com/jira/
I'm looking to write unit tests for a method such as this one:
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
ISPMembershipUserDao userDao = GetISPMembershipUserDao();
if (ValidateUser(username, password))
{
SPMembershipUser user = userDao.GetUserByUserName(username);
user.PasswordQuestion = newPasswordQuestion;
user.PasswordAnswer = newPasswordAnswer;
userDao.Save(user);
return true;
}
return false;
}
It's a fairly straight-forward method to test. I'm using the Rhino Mocks framework. But one aspect has me questioning myself. I stub the DAO object and its save method, and I'm wondering how deeply I should test that user object that is passed to the save method. Should I assert that every property of that object is as I expect it to be? Or should I only assert that the PasswordQuestion and PasswordAnswer properites have the correct values? The former seems right to me, as I should make sure that only those two properties have been modified, and the others haven't been touched.
I was hoping some people could give their opinions on this. Is there a rule of thumb or pattern to keep in mind for these types of situations?
Warning: personal opinion ahead
Ok, now that that's out of the way.... for me, it comes down to what I need to do to feel that my code properly implements the needed logic. In this case? I'd have two test cases:
Dealing with ValidateUser returning false
Should return false
Save should not have been called
Dealing with ValidateUser returning true
Should return true
Save should have been called
Object passed to save has the modified question and answer
No checks of other properties on user object
However, if/when I got a bug filed that affected this part of the code, I'd add whatever (initially failing) tests were needed to cover the bug, fix the bug, and leave the tests.
Since it's so easy to set up a constraint here, why not test it to ensure there are no side-effects to your method?
stubbedUserDao.AssertWasCalled(x => x.Save(null), o => {
o.IgnoreArguments();
o.Constraints(Property.AllPropertiesMatch(expectedMatchingUser));
});