<!--
{
  "availability" : [
    "iOS: 1.0.0 -",
    "iPadOS: 1.0.0 -",
    "macCatalyst: 1.0.0 -",
    "macOS: 10.0.0 -",
    "tvOS: 1.0.0 -",
    "visionOS: 1.0.0 -",
    "watchOS: 1.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "ObjectiveC",
  "identifier" : "/documentation/ObjectiveC/NSObjectProtocol/perform(_:)",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Method",
  "symbol" : {
    "kind" : "Instance Method",
    "modules" : [
      "Objective-C Runtime"
    ],
    "preciseIdentifier" : "c:objc(pl)NSObject(im)performSelector:"
  },
  "title" : "perform(_:)"
}
-->

# perform(_:)

Sends a specified message to the receiver and returns the result of the message.

```
func perform(_ aSelector: Selector!) -> Unmanaged<AnyObject>!
```

## Parameters

`aSelector`

A selector identifying the message to send. The message should take no arguments. If `aSelector` is `NULL`, an <doc://com.apple.documentation/documentation/Foundation/NSExceptionName/invalidArgumentException> is raised.

## Return Value

An object that is the result of the message.

## Discussion

Calling the [`perform(_:)`](/documentation/ObjectiveC/NSObjectProtocol/perform(_:)) method is equivalent to sending the `aSelector` message directly to the receiver. For example, the following both do the same thing if `anObject` is an instance of `MyObject`:

```objc
id aClone = [anObject copy];
id aClone = [anObject performSelector:@selector(copy)];
id aClone = [anObject performSelector:sel_getUid("copy")];
```

The [`perform(_:)`](/documentation/ObjectiveC/NSObjectProtocol/perform(_:)) method allows you to send messages that aren’t determined until run-time. This means that you can pass a variable selector as the argument:

```objc
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
id returnedObject = [anObject performSelector:aSelector];
```

Use caution when doing this. This method returns an implicitly unwrapped optional unmanaged pointer to an `AnyObject` instance (<doc://com.apple.documentation/documentation/Swift/Unmanaged>`<`<doc://com.apple.documentation/documentation/Swift/AnyObject>`>!`).  It’s up to you to decide how to bring the instance into Swift’s memory management scheme.  Different messages require different memory management strategies for their returned objects, and it might not be obvious which to use.

Usually, a caller isn’t responsible for the memory of a returned instance, in which case you use <doc://com.apple.documentation/documentation/Swift/Unmanaged/takeUnretainedValue()>, as shown above. However, for any of the creation methods, such as [`copy()`](/documentation/ObjectiveC/NSObject-swift.class/copy()), the caller is responsible, and you use <doc://com.apple.documentation/documentation/Swift/Unmanaged/takeRetainedValue()> instead. See [Memory Management Policy](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994) in [Advanced Memory Management Programming Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html#//apple_ref/doc/uid/10000011i) for a description of ownership expectations.

Due to this uncertainty, the compiler generates a warning if you supply a variable selector while using ARC to manage memory. Because it can’t determine ownership of the returned object at compile-time, ARC makes the assumption that the caller does *not* need to take ownership, but this may not be true. The compiler warning alerts you to the potential for a memory leak.

To avoid the warning, if you know that `aSelector` has no return value, you might be able to use [`performSelector(onMainThread:with:waitUntilDone:)`](/documentation/ObjectiveC/NSObject-swift.class/performSelector(onMainThread:with:waitUntilDone:)) or one of the related methods available in [`NSObject`](/documentation/ObjectiveC/NSObject-swift.class).

For a more general solution, use <doc://com.apple.documentation/documentation/Foundation/NSInvocation> to construct a message that you can invoke with an arbitrary argument list and return value.

Alternatively, consider restructuring your code to use blocks as a means of passing chunks of functionality through an API. See [Blocks Programming Topics](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html#//apple_ref/doc/uid/TP40007502) for details.

> Important:
> Because of the inherent lack of type safety, this API isn’t recommended for use in Swift unless your code specifically relies on the dynamic method resolution provided by the Objective-C run-time.
> 
> For more information about using selectors in Swift and alternatives to the ``doc://com.apple.objectivec/documentation/ObjectiveC/NSObjectProtocol/perform(_:)`` function, read <doc://com.apple.documentation/documentation/Swift/using-objective-c-runtime-features-in-swift>.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)