Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: ios/chrome/browser/ui/util/label_observer.mm

Issue 2819283004: [ObjC ARC] Converts ios/chrome/browser/ui/util:util to ARC. (Closed)
Patch Set: Fix copy for block Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/ui/util/label_observer.h" 5 #import "ios/chrome/browser/ui/util/label_observer.h"
6 6
7 #import <objc/runtime.h> 7 #import <objc/runtime.h>
8 8
9 #import "base/ios/weak_nsobject.h"
10 #import "base/mac/scoped_block.h"
11 #import "base/mac/scoped_nsobject.h"
12 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/sys_string_conversions.h"
13 10
11 #if !defined(__has_feature) || !__has_feature(objc_arc)
12 #error "This file requires ARC support."
13 #endif
14
14 namespace { 15 namespace {
15 // The key under which LabelObservers are associated with their labels. 16 // The key under which LabelObservers are associated with their labels.
16 const void* const kLabelObserverKey = &kLabelObserverKey; 17 const void* const kLabelObserverKey = &kLabelObserverKey;
17 // Attempts to convert |value| to a string. 18 // Attempts to convert |value| to a string.
18 NSString* GetStringValue(id value) { 19 NSString* GetStringValue(id value) {
19 if ([value isKindOfClass:[NSString class]]) 20 if ([value isKindOfClass:[NSString class]])
20 return static_cast<NSString*>(value); 21 return static_cast<NSString*>(value);
21 if ([value respondsToSelector:@selector(string)]) 22 if ([value respondsToSelector:@selector(string)])
22 return [value performSelector:@selector(string)]; 23 return [value performSelector:@selector(string)];
23 return nil; 24 return nil;
24 } 25 }
25 } 26 }
26 27
27 @interface LabelObserver () { 28 @interface LabelObserver () {
28 // The label being observed. 29 // The label being observed.
29 base::WeakNSObject<UILabel> _label; 30 __weak UILabel* _label;
30 // Arrays used to store registered actions. 31 // Arrays used to store registered actions.
31 base::scoped_nsobject<NSMutableArray> _styleActions; 32 NSMutableArray* _styleActions;
32 base::scoped_nsobject<NSMutableArray> _layoutActions; 33 NSMutableArray* _layoutActions;
33 base::scoped_nsobject<NSMutableArray> _textActions; 34 NSMutableArray* _textActions;
34 } 35 }
35 36
36 // Whether or not observer actions are currently being executed. This is used 37 // Whether or not observer actions are currently being executed. This is used
37 // to prevent infinite loops caused by a LinkObserverAction updating a 38 // to prevent infinite loops caused by a LinkObserverAction updating a
38 // property on |_label|. 39 // property on |_label|.
39 @property(nonatomic, assign, getter=isRespondingToKVO) BOOL respondingToKVO; 40 @property(nonatomic, assign, getter=isRespondingToKVO) BOOL respondingToKVO;
40 41
41 // The number of times this observer has been asked to observe the label. When 42 // The number of times this observer has been asked to observe the label. When
42 // reaching zero, the label stops being observed. 43 // reaching zero, the label stops being observed.
43 @property(nonatomic, assign) NSInteger observingCount; 44 @property(nonatomic, assign) NSInteger observingCount;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 ]]; 83 ]];
83 layoutKeys = [[NSSet alloc] 84 layoutKeys = [[NSSet alloc]
84 initWithArray:@[ @"bounds", @"frame", @"superview", @"center" ]]; 85 initWithArray:@[ @"bounds", @"frame", @"superview", @"center" ]];
85 textKeys = [[NSSet alloc] initWithArray:@[ @"text", @"attributedText" ]]; 86 textKeys = [[NSSet alloc] initWithArray:@[ @"text", @"attributedText" ]];
86 } 87 }
87 } 88 }
88 89
89 - (instancetype)initWithLabel:(UILabel*)label { 90 - (instancetype)initWithLabel:(UILabel*)label {
90 if ((self = [super init])) { 91 if ((self = [super init])) {
91 DCHECK(label); 92 DCHECK(label);
92 _label.reset(label); 93 _label = label;
93 [self resetLabelAttributes]; 94 [self resetLabelAttributes];
94 } 95 }
95 return self; 96 return self;
96 } 97 }
97 98
98 - (void)dealloc { 99 - (void)dealloc {
99 objc_setAssociatedObject(_label, kLabelObserverKey, nil, 100 objc_setAssociatedObject(_label, kLabelObserverKey, nil,
100 OBJC_ASSOCIATION_ASSIGN); 101 OBJC_ASSOCIATION_ASSIGN);
101 [super dealloc];
102 } 102 }
103 103
104 #pragma mark - Public interface 104 #pragma mark - Public interface
105 105
106 + (instancetype)observerForLabel:(UILabel*)label { 106 + (instancetype)observerForLabel:(UILabel*)label {
107 if (!label) 107 if (!label)
108 return nil; 108 return nil;
109 id observer = objc_getAssociatedObject(label, kLabelObserverKey); 109 id observer = objc_getAssociatedObject(label, kLabelObserverKey);
110 if (!observer) { 110 if (!observer) {
111 observer = [[LabelObserver alloc] initWithLabel:label]; 111 observer = [[LabelObserver alloc] initWithLabel:label];
112 objc_setAssociatedObject(label, kLabelObserverKey, observer, 112 objc_setAssociatedObject(label, kLabelObserverKey, observer,
113 OBJC_ASSOCIATION_ASSIGN); 113 OBJC_ASSOCIATION_ASSIGN);
114 [observer autorelease];
115 } 114 }
116 return observer; 115 return observer;
117 } 116 }
118 117
119 - (void)startObserving { 118 - (void)startObserving {
120 if (self.observingCount == 0) { 119 if (self.observingCount == 0) {
121 [self registerAsObserver]; 120 [self registerAsObserver];
122 } 121 }
123 self.observingCount++; 122 self.observingCount++;
124 } 123 }
125 124
126 - (void)stopObserving { 125 - (void)stopObserving {
127 if (self.observingCount == 0) 126 if (self.observingCount == 0)
128 return; 127 return;
129 128
130 self.observingCount--; 129 self.observingCount--;
131 if (self.observingCount == 0) { 130 if (self.observingCount == 0) {
132 [self removeObserver]; 131 [self removeObserver];
133 } 132 }
134 } 133 }
135 134
136 - (void)addStyleChangedAction:(LabelObserverAction)action { 135 - (void)addStyleChangedAction:(LabelObserverAction)action {
137 DCHECK(action); 136 DCHECK(action);
138 if (!_styleActions) 137 if (!_styleActions)
139 _styleActions.reset([[NSMutableArray alloc] init]); 138 _styleActions = [[NSMutableArray alloc] init];
140 base::mac::ScopedBlock<LabelObserverAction> actionCopy([action copy]); 139 LabelObserverAction actionCopy = [action copy];
141 [_styleActions addObject:actionCopy]; 140 [_styleActions addObject:actionCopy];
142 } 141 }
143 142
144 - (void)addLayoutChangedAction:(LabelObserverAction)action { 143 - (void)addLayoutChangedAction:(LabelObserverAction)action {
145 DCHECK(action); 144 DCHECK(action);
146 if (!_layoutActions) 145 if (!_layoutActions)
147 _layoutActions.reset([[NSMutableArray alloc] init]); 146 _layoutActions = [[NSMutableArray alloc] init];
148 base::mac::ScopedBlock<LabelObserverAction> actionCopy([action copy]); 147 LabelObserverAction actionCopy = [action copy];
149 [_layoutActions addObject:actionCopy]; 148 [_layoutActions addObject:actionCopy];
150 } 149 }
151 150
152 - (void)addTextChangedAction:(LabelObserverAction)action { 151 - (void)addTextChangedAction:(LabelObserverAction)action {
153 DCHECK(action); 152 DCHECK(action);
154 if (!_textActions) 153 if (!_textActions)
155 _textActions.reset([[NSMutableArray alloc] init]); 154 _textActions = [[NSMutableArray alloc] init];
156 base::mac::ScopedBlock<LabelObserverAction> actionCopy([action copy]); 155 LabelObserverAction actionCopy = [action copy];
157 [_textActions addObject:actionCopy]; 156 [_textActions addObject:actionCopy];
158 } 157 }
159 158
160 #pragma mark - 159 #pragma mark -
161 160
162 - (void)registerAsObserver { 161 - (void)registerAsObserver {
163 for (NSSet* keySet in @[ styleKeys, layoutKeys, textKeys ]) { 162 for (NSSet* keySet in @[ styleKeys, layoutKeys, textKeys ]) {
164 for (NSString* key in keySet) { 163 for (NSString* key in keySet) {
165 [_label addObserver:self 164 [_label addObserver:self
166 forKeyPath:key 165 forKeyPath:key
(...skipping 16 matching lines...) Expand all
183 action(_label); 182 action(_label);
184 } 183 }
185 184
186 - (void)resetLabelAttributes { 185 - (void)resetLabelAttributes {
187 if ([_label attributedText] || ![_label text]) 186 if ([_label attributedText] || ![_label text])
188 return; 187 return;
189 NSMutableDictionary* labelStyle = 188 NSMutableDictionary* labelStyle =
190 [NSMutableDictionary dictionaryWithCapacity:styleKeys.count]; 189 [NSMutableDictionary dictionaryWithCapacity:styleKeys.count];
191 for (NSString* property in styleKeys) 190 for (NSString* property in styleKeys)
192 labelStyle[property] = [_label valueForKey:property]; 191 labelStyle[property] = [_label valueForKey:property];
193 base::scoped_nsobject<NSAttributedString> attributedText( 192 NSAttributedString* attributedText =
194 [[NSAttributedString alloc] initWithString:[_label text]]); 193 [[NSAttributedString alloc] initWithString:[_label text]];
195 [_label setAttributedText:attributedText]; 194 [_label setAttributedText:attributedText];
196 for (NSString* property in styleKeys) 195 for (NSString* property in styleKeys)
197 [_label setValue:labelStyle[property] forKey:property]; 196 [_label setValue:labelStyle[property] forKey:property];
198 } 197 }
199 198
200 - (void)observeValueForKeyPath:(NSString*)key 199 - (void)observeValueForKeyPath:(NSString*)key
201 ofObject:(id)object 200 ofObject:(id)object
202 change:(NSDictionary*)change 201 change:(NSDictionary*)change
203 context:(void*)context { 202 context:(void*)context {
204 if (self.respondingToKVO) 203 if (self.respondingToKVO)
205 return; 204 return;
206 self.respondingToKVO = YES; 205 self.respondingToKVO = YES;
207 DCHECK_EQ(object, _label.get()); 206 DCHECK_EQ(object, _label);
208 if ([styleKeys containsObject:key]) { 207 if ([styleKeys containsObject:key]) {
209 [self performActions:_styleActions]; 208 [self performActions:_styleActions];
210 } else if ([layoutKeys containsObject:key]) { 209 } else if ([layoutKeys containsObject:key]) {
211 [self performActions:_layoutActions]; 210 [self performActions:_layoutActions];
212 } else if ([textKeys containsObject:key]) { 211 } else if ([textKeys containsObject:key]) {
213 NSString* oldText = GetStringValue(change[NSKeyValueChangeOldKey]); 212 NSString* oldText = GetStringValue(change[NSKeyValueChangeOldKey]);
214 NSString* newText = GetStringValue(change[NSKeyValueChangeNewKey]); 213 NSString* newText = GetStringValue(change[NSKeyValueChangeNewKey]);
215 if (![oldText isEqualToString:newText]) 214 if (![oldText isEqualToString:newText])
216 [self resetLabelAttributes]; 215 [self resetLabelAttributes];
217 [self performActions:_textActions]; 216 [self performActions:_textActions];
218 } else { 217 } else {
219 NOTREACHED() << "Unexpected label key <" << base::SysNSStringToUTF8(key) 218 NOTREACHED() << "Unexpected label key <" << base::SysNSStringToUTF8(key)
220 << "> observed"; 219 << "> observed";
221 } 220 }
222 self.respondingToKVO = NO; 221 self.respondingToKVO = NO;
223 } 222 }
224 223
225 @end 224 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698