0
# Protocol Support
1
2
Support for Objective-C formal and informal protocols, enabling proper protocol conformance, method requirements, and protocol-based programming patterns.
3
4
## Capabilities
5
6
### Formal Protocol Support
7
8
Functions for working with Objective-C formal protocols, equivalent to `@protocol()` declarations.
9
10
```python { .api }
11
def protocolNamed(name):
12
"""
13
Get a formal protocol by name (equivalent to @protocol(name) in Objective-C).
14
15
Args:
16
name (str): Name of the protocol to retrieve
17
18
Returns:
19
Protocol object that can be used for conformance checking
20
21
Raises:
22
ProtocolError: If protocol cannot be found or loaded
23
"""
24
```
25
26
### Informal Protocol Support
27
28
Functions for working with Objective-C informal protocols (categories on NSObject).
29
30
```python { .api }
31
def informal_protocol(name):
32
"""
33
Create or access an informal protocol.
34
35
Args:
36
name (str): Name of the informal protocol
37
38
Returns:
39
Informal protocol object for method declarations
40
"""
41
```
42
43
### Protocol Error Handling
44
45
Exception class for protocol-related errors.
46
47
```python { .api }
48
class ProtocolError(Exception):
49
"""
50
Exception raised for protocol-related errors such as:
51
- Protocol not found
52
- Protocol loading failures
53
- Protocol conformance issues
54
"""
55
```
56
57
**Usage Examples:**
58
59
```python
60
import objc
61
from objc import protocolNamed, informal_protocol, ProtocolError
62
63
# Working with formal protocols
64
try:
65
# Get a system protocol
66
delegate_protocol = protocolNamed("NSApplicationDelegate")
67
table_delegate = protocolNamed("NSTableViewDelegate")
68
69
# Check if class conforms to protocol
70
# (typically done through runtime introspection)
71
72
except ProtocolError as e:
73
print(f"Protocol error: {e}")
74
75
# Implementing protocol methods in Python class
76
class MyAppDelegate:
77
"""Application delegate implementing NSApplicationDelegate protocol."""
78
79
@objc.objc_method
80
def applicationDidFinishLaunching_(self, notification):
81
"""Required NSApplicationDelegate method."""
82
print("Application finished launching")
83
84
@objc.objc_method
85
def applicationShouldTerminate_(self, sender):
86
"""Optional NSApplicationDelegate method."""
87
return True # Allow termination
88
89
class MyTableDelegate:
90
"""Table view delegate implementing NSTableViewDelegate protocol."""
91
92
@objc.objc_method
93
def tableView_heightOfRow_(self, tableView, row):
94
"""NSTableViewDelegate method for row height."""
95
return 25.0
96
97
@objc.objc_method
98
def tableView_shouldSelectRow_(self, tableView, row):
99
"""NSTableViewDelegate method for selection control."""
100
return True
101
102
# Working with informal protocols
103
# Informal protocols are typically used for optional method collections
104
my_informal = informal_protocol("MyCustomProtocol")
105
```
106
107
### Protocol Conformance Patterns
108
109
PyObjC enables protocol conformance through method implementation:
110
111
1. **Formal Protocols**: Implement required and optional methods as defined by the protocol
112
2. **Method Signatures**: Use `@objc_method` decorator with appropriate signatures
113
3. **Runtime Registration**: Methods are automatically registered with the Objective-C runtime
114
4. **Type Safety**: Protocol conformance is checked at runtime by the Objective-C system
115
116
### Common Protocol Patterns
117
118
```python
119
# Delegate pattern implementation
120
class MyController:
121
def __init__(self):
122
self.tableView = None
123
124
def setupTableView(self):
125
# Set self as delegate (must conform to protocol)
126
self.tableView.setDelegate_(self)
127
128
# Implement required delegate methods
129
@objc.objc_method
130
def numberOfRowsInTableView_(self, tableView):
131
return 10
132
133
@objc.objc_method
134
def tableView_objectValueForTableColumn_row_(self, tableView, column, row):
135
return f"Row {row}"
136
137
# Data source pattern implementation
138
class MyDataSource:
139
@objc.objc_method
140
def tableView_numberOfRowsInSection_(self, tableView, section):
141
return len(self.data)
142
143
@objc.objc_method
144
def tableView_cellForRowAtIndexPath_(self, tableView, indexPath):
145
# Return configured cell
146
pass
147
```