performSelector:withObject: and its retain behavior
Asked Answered
S

2

11

This is an already answer question within SO but I cannot find it in the Apple documentation anywhere. Could you point me in the right direction?

Within the following topics

Do I have to retain an object before passing it to -performSelector:withObject:afterDelay:?

the effect on retain count of performSelector:withObject:afterDelay:inModes

Is object that calls performSelector:withObject:afterDelay get retained by the NSRunLoop?

the default behaviour seems to be the following: it retains the receiver and the argument(s).

I'm using the following code

[[self delegate] performSelector:@selector(tryToSendStoreData:) withObject:userData];

where userData is an autoreleased oject.

Logging the retain count (I know that it could be not valid to do it) the data passed in increments its retain count. When the method is invoked on the delegate, the retain count is not equal to one.

So, my question is: do I need to perform some memory management to avoid leaks or do I have to trust on Apple stuff? Here I'm speaking as an agnostic since I cannot find the right docs.

Thank you in advance.

Stephaniestephannie answered 27/6, 2012 at 14:43 Comment(6)
I believe that retain count is no longer accurate under ARCGeddes
@Cake I'm not using ARC in this project. Thanks.Stephaniestephannie
For ARC enabled project you can look into - #7017781Sanmiguel
And as you are not using ARC, so simple answer for this is NO, you don't need to handle memory with perform selector as discussed in above mentioned thread.Sanmiguel
@Sanmiguel Thank you. Do you know where I can find the right docs? I can't find any documentation on it. Thanks.Stephaniestephannie
@Flex_Addicted - Docs are updated now as ARC is now used.So you will not able to find what was there earlier. But you can be sure of what is mentioned in above threads.Sanmiguel
A
11

You are looking at the wrong function in the documentation.

Retain

performSelector:withObject:afterDelay: and similar functions (with afterDelay) retain the receiver and arguments, because the execute later

No Retain

performSelector:withObject: and similar functions (without afterDelay) do not retain anything, since they just call the function directly.

[[self delegate] performSelector:@selector(tryToSendStoreData:) withObject:userData];

does the exact same thing as

[[self delegate] tryToSendStoreData:userData];
Animalize answered 27/6, 2012 at 17:56 Comment(4)
+1 for your support. But I cannot find any doc for this. In addition, why does the retain count increments its value after performing that call? Thank you.Stephaniestephannie
@Flex_Addicted: it's common for functions to retain and then autorelease their arguments, for additional safety. That's why looking at the retain count is uselessAnimalize
Thanks. Then, if you any doc on it, please link it. Cheers.Stephaniestephannie
@Flex_Addicted: https://mcmap.net/q/193328/-when-to-use-retaincount Never use retainCount. It is not usefulAnimalize
S
12

While @newacct gave the correct answer, but it was not for the question that @Flex_Addicted had asked, i.e. citations from Apple's documentation that the observed behaviour is indeed guranteed. Below is a (partial) citation, but we'll have to go through a couple of hoops to get there -

The documentation for performSelector:withObject:afterDelay: states that

This method sets up a timer to perform the aSelector message on the current thread’s run loop.

so next we head over to the documentation for NSRunLoop and there we find that only one method exists that allows the capability to enqueue stuff on the run loop -
performSelector:target:argument:order:modes:, whose documentation states that

This method sets up a timer to perform the aSelector message on the current thread’s run loop at the start of the next run loop iteration. The timer is configured to run in the modes specified by the modes parameter...The receiver retains the target and anArgument objects until the timer for the selector fires, and then releases them as part of its cleanup.

Of course, nothing guarantees that [NSObject performSelector:withObject:afterDelay:] always uses [NSRunLoop performSelector:target:argument:order:modes:] (although this answer would be complete if someone could come up with documentation for that), but at least this is a step towards the mystery of answering the riddles the holy scriptures riddle us with.

Sardius answered 19/10, 2012 at 7:53 Comment(0)
A
11

You are looking at the wrong function in the documentation.

Retain

performSelector:withObject:afterDelay: and similar functions (with afterDelay) retain the receiver and arguments, because the execute later

No Retain

performSelector:withObject: and similar functions (without afterDelay) do not retain anything, since they just call the function directly.

[[self delegate] performSelector:@selector(tryToSendStoreData:) withObject:userData];

does the exact same thing as

[[self delegate] tryToSendStoreData:userData];
Animalize answered 27/6, 2012 at 17:56 Comment(4)
+1 for your support. But I cannot find any doc for this. In addition, why does the retain count increments its value after performing that call? Thank you.Stephaniestephannie
@Flex_Addicted: it's common for functions to retain and then autorelease their arguments, for additional safety. That's why looking at the retain count is uselessAnimalize
Thanks. Then, if you any doc on it, please link it. Cheers.Stephaniestephannie
@Flex_Addicted: https://mcmap.net/q/193328/-when-to-use-retaincount Never use retainCount. It is not usefulAnimalize

© 2022 - 2024 — McMap. All rights reserved.