├── ObserverSet.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── ObserverSetTests
├── Info.plist
├── CaptureSemanticsTests.swift
└── ObserverSetTests.swift
├── ObserverSet
├── Info.plist
└── ObserverSet.swift
└── LICENSE
/ObserverSet.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ObserverSetTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ObserverSet/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSHumanReadableCopyright
24 | Copyright © 2015 Mike Ash. All rights reserved.
25 | NSPrincipalClass
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ObserverSet is distributed under a BSD license, as listed below.
2 |
3 |
4 | Copyright (c) 2015, Michael Ash
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8 |
9 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 |
11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12 |
13 | Neither the name of Michael Ash nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/ObserverSetTests/CaptureSemanticsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // ObserverSet
4 | //
5 | // Created by Karl Traunmüller on 26/02/16.
6 | // Copyright © 2016 Mike Ash. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import ObserverSet
11 |
12 | class CaptureSemanticsTests: XCTestCase {
13 |
14 | class TestObservee {
15 | let event = ObserverSet()
16 | }
17 |
18 | class TestObserverThatRegistersClosure {
19 | let observee = TestObservee()
20 |
21 | init() {
22 | observee.event.add({ [weak self] () -> Void in
23 | self?.foo()
24 | })
25 | }
26 |
27 | private func foo() {
28 | }
29 | }
30 |
31 | class TestObserverThatRegistersUnboundMemberFunction {
32 | let observee = TestObservee()
33 |
34 | init() {
35 | observee.event.add(self, self.dynamicType.voidHandler)
36 | }
37 |
38 | func voidHandler() {
39 | }
40 | }
41 |
42 | class TestObserverThatRegistersBoundMemberFunction {
43 | let observee = TestObservee()
44 |
45 | init() {
46 | observee.event.add(voidHandler)
47 | }
48 |
49 | func voidHandler() {
50 | }
51 | }
52 |
53 | func testObserverThatRegistersClosure() {
54 | weak var obj: AnyObject? = TestObserverThatRegistersClosure()
55 | XCTAssertNil(obj)
56 | }
57 |
58 | func testObserverThatRegistersUnboundMemberFunction() {
59 | weak var obj: AnyObject? = TestObserverThatRegistersUnboundMemberFunction()
60 | XCTAssertNil(obj)
61 | }
62 |
63 | // see also:
64 | // - https://devforums.apple.com/thread/237021
65 | // - https://devforums.apple.com/message/1012414#1012414
66 | func testObserverThatRegistersBoundMemberFunction() {
67 | weak var obj: AnyObject? = TestObserverThatRegistersBoundMemberFunction()
68 | XCTAssertNotNil(obj, "Registering a bound member function may result in a strong reference cycle. Use the overload of add() that takes an observer object and an unbound member function.")
69 | }
70 |
71 | }
--------------------------------------------------------------------------------
/ObserverSet/ObserverSet.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ObserverSet.swift
3 | // ObserverSet
4 | //
5 | // Created by Mike Ash on 1/22/15.
6 | // Copyright (c) 2015 Mike Ash. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public class ObserverSetEntry {
12 | private weak var object: AnyObject?
13 | private let f: AnyObject -> Parameters -> Void
14 |
15 | private init(object: AnyObject, f: AnyObject -> Parameters -> Void) {
16 | self.object = object
17 | self.f = f
18 | }
19 | }
20 |
21 | public class ObserverSet: CustomStringConvertible {
22 | // Locking support
23 |
24 | private var queue = dispatch_queue_create("com.mikeash.ObserverSet", nil)
25 |
26 | private func synchronized(f: Void -> Void) {
27 | dispatch_sync(queue, f)
28 | }
29 |
30 |
31 | // Main implementation
32 |
33 | private var entries: [ObserverSetEntry] = []
34 |
35 | public init() {}
36 |
37 | public func add(object: T, _ f: T -> Parameters -> Void) -> ObserverSetEntry {
38 | let entry = ObserverSetEntry(object: object, f: { f($0 as! T) })
39 | synchronized {
40 | self.entries.append(entry)
41 | }
42 | return entry
43 | }
44 |
45 | public func add(f: Parameters -> Void) -> ObserverSetEntry {
46 | return self.add(self, { ignored in f })
47 | }
48 |
49 | public func remove(entry: ObserverSetEntry) {
50 | synchronized {
51 | self.entries = self.entries.filter{ $0 !== entry }
52 | }
53 | }
54 |
55 | public func notify(parameters: Parameters) {
56 | var toCall: [Parameters -> Void] = []
57 |
58 | synchronized {
59 | for entry in self.entries {
60 | if let object: AnyObject = entry.object {
61 | toCall.append(entry.f(object))
62 | }
63 | }
64 | self.entries = self.entries.filter{ $0.object != nil }
65 | }
66 |
67 | for f in toCall {
68 | f(parameters)
69 | }
70 | }
71 |
72 |
73 | // MARK: CustomStringConvertible
74 |
75 | public var description: String {
76 | var entries: [ObserverSetEntry] = []
77 | synchronized {
78 | entries = self.entries
79 | }
80 |
81 | let strings = entries.map{
82 | entry in
83 | (entry.object === self
84 | ? "\(entry.f)"
85 | : "\(entry.object) \(entry.f)")
86 | }
87 | let joined = strings.joinWithSeparator(", ")
88 |
89 | return "\(Mirror(reflecting: self).description): (\(joined))"
90 | }
91 | }
92 |
93 |
--------------------------------------------------------------------------------
/ObserverSetTests/ObserverSetTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ObserverSetTests.swift
3 | // ObserverSetTests
4 | //
5 | // Created by Mike Ash on 1/22/15.
6 | // Copyright (c) 2015 Mike Ash. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import XCTest
11 |
12 | import ObserverSet
13 |
14 | class ObserverSetTests: XCTestCase {
15 | class TestObservee {
16 | let voidObservers = ObserverSet()
17 | let stringObservers = ObserverSet()
18 | let twoStringObservers = ObserverSet<(String, String)>()
19 | let intObservers = ObserverSet<(Int, Int)>()
20 | let intAndStringObservers = ObserverSet<(Int, String)>()
21 | let namedParameterObservers = ObserverSet<(name: String, count: Int)>()
22 |
23 | func testNotify() {
24 | voidObservers.notify()
25 | stringObservers.notify("Sup")
26 | twoStringObservers.notify(("hello", "world"))
27 | intObservers.notify((42, 43))
28 | intAndStringObservers.notify((42, "hello"))
29 | namedParameterObservers.notify((name: "someName", count: 42))
30 | }
31 | }
32 |
33 | class TestObserver {
34 | init(observee: TestObservee) {
35 | observee.voidObservers.add(self, self.dynamicType.voidSent)
36 | observee.stringObservers.add(self, self.dynamicType.stringChanged)
37 | observee.twoStringObservers.add(self, self.dynamicType.twoStringChanged)
38 | observee.intObservers.add(self, self.dynamicType.intChanged)
39 | observee.intAndStringObservers.add(self, self.dynamicType.intAndStringChanged)
40 | observee.namedParameterObservers.add(self, self.dynamicType.namedParameterSent)
41 | }
42 |
43 | deinit {
44 | print("deinit!!!!")
45 | }
46 |
47 | func voidSent() {
48 | print("void sent")
49 | }
50 |
51 | func stringChanged(s: String) {
52 | print("stringChanged: " + s)
53 | }
54 |
55 | func twoStringChanged(s1: String, s2: String) {
56 | print("twoStringChanged: \(s1) \(s2)")
57 | }
58 |
59 | func intChanged(i: Int, j: Int) {
60 | print("intChanged: \(i) \(j)")
61 | }
62 |
63 | func intAndStringChanged(i: Int, s: String) {
64 | print("intAndStringChanged: \(i) \(s)")
65 | }
66 |
67 | func namedParameterSent(name: String, count: Int) {
68 | print("Named parameters: \(name) \(count)")
69 | }
70 | }
71 |
72 | func testBasics() {
73 | let observee = TestObservee()
74 | var obj: TestObserver? = TestObserver(observee: observee)
75 |
76 | let token = observee.intAndStringObservers.add{ print("int and string closure: \($0) \($1)") }
77 | print("intAndStringObservers: \(observee.intAndStringObservers.description)")
78 |
79 | observee.testNotify()
80 | print("Destroying test observer \(obj)")
81 | obj = nil
82 | observee.testNotify()
83 | observee.intAndStringObservers.remove(token)
84 | observee.testNotify()
85 |
86 | print("intAndStringObservers: \(observee.intAndStringObservers.description)")
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/ObserverSet.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8E904FD01C80206600383B20 /* CaptureSemanticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E904FCF1C80206600383B20 /* CaptureSemanticsTests.swift */; };
11 | C2CC54651A71D8610084E87D /* ObserverSet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2CC54591A71D8610084E87D /* ObserverSet.framework */; };
12 | C2CC546C1A71D8610084E87D /* ObserverSetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2CC546B1A71D8610084E87D /* ObserverSetTests.swift */; };
13 | C2CC54761A71D8FE0084E87D /* ObserverSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2CC54751A71D8FE0084E87D /* ObserverSet.swift */; };
14 | /* End PBXBuildFile section */
15 |
16 | /* Begin PBXContainerItemProxy section */
17 | C2CC54661A71D8610084E87D /* PBXContainerItemProxy */ = {
18 | isa = PBXContainerItemProxy;
19 | containerPortal = C2CC54501A71D8610084E87D /* Project object */;
20 | proxyType = 1;
21 | remoteGlobalIDString = C2CC54581A71D8610084E87D;
22 | remoteInfo = ObserverSet;
23 | };
24 | /* End PBXContainerItemProxy section */
25 |
26 | /* Begin PBXFileReference section */
27 | 8E904FCF1C80206600383B20 /* CaptureSemanticsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaptureSemanticsTests.swift; sourceTree = ""; };
28 | C2CC54591A71D8610084E87D /* ObserverSet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObserverSet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
29 | C2CC545D1A71D8610084E87D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
30 | C2CC54641A71D8610084E87D /* ObserverSetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ObserverSetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
31 | C2CC546A1A71D8610084E87D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | C2CC546B1A71D8610084E87D /* ObserverSetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObserverSetTests.swift; sourceTree = ""; };
33 | C2CC54751A71D8FE0084E87D /* ObserverSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObserverSet.swift; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | C2CC54551A71D8610084E87D /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | C2CC54611A71D8610084E87D /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | C2CC54651A71D8610084E87D /* ObserverSet.framework in Frameworks */,
49 | );
50 | runOnlyForDeploymentPostprocessing = 0;
51 | };
52 | /* End PBXFrameworksBuildPhase section */
53 |
54 | /* Begin PBXGroup section */
55 | C2CC544F1A71D8610084E87D = {
56 | isa = PBXGroup;
57 | children = (
58 | C2CC545B1A71D8610084E87D /* ObserverSet */,
59 | C2CC54681A71D8610084E87D /* ObserverSetTests */,
60 | C2CC545A1A71D8610084E87D /* Products */,
61 | );
62 | sourceTree = "";
63 | };
64 | C2CC545A1A71D8610084E87D /* Products */ = {
65 | isa = PBXGroup;
66 | children = (
67 | C2CC54591A71D8610084E87D /* ObserverSet.framework */,
68 | C2CC54641A71D8610084E87D /* ObserverSetTests.xctest */,
69 | );
70 | name = Products;
71 | sourceTree = "";
72 | };
73 | C2CC545B1A71D8610084E87D /* ObserverSet */ = {
74 | isa = PBXGroup;
75 | children = (
76 | C2CC54751A71D8FE0084E87D /* ObserverSet.swift */,
77 | C2CC545C1A71D8610084E87D /* Supporting Files */,
78 | );
79 | path = ObserverSet;
80 | sourceTree = "";
81 | };
82 | C2CC545C1A71D8610084E87D /* Supporting Files */ = {
83 | isa = PBXGroup;
84 | children = (
85 | C2CC545D1A71D8610084E87D /* Info.plist */,
86 | );
87 | name = "Supporting Files";
88 | sourceTree = "";
89 | };
90 | C2CC54681A71D8610084E87D /* ObserverSetTests */ = {
91 | isa = PBXGroup;
92 | children = (
93 | C2CC546B1A71D8610084E87D /* ObserverSetTests.swift */,
94 | 8E904FCF1C80206600383B20 /* CaptureSemanticsTests.swift */,
95 | C2CC54691A71D8610084E87D /* Supporting Files */,
96 | );
97 | path = ObserverSetTests;
98 | sourceTree = "";
99 | };
100 | C2CC54691A71D8610084E87D /* Supporting Files */ = {
101 | isa = PBXGroup;
102 | children = (
103 | C2CC546A1A71D8610084E87D /* Info.plist */,
104 | );
105 | name = "Supporting Files";
106 | sourceTree = "";
107 | };
108 | /* End PBXGroup section */
109 |
110 | /* Begin PBXHeadersBuildPhase section */
111 | C2CC54561A71D8610084E87D /* Headers */ = {
112 | isa = PBXHeadersBuildPhase;
113 | buildActionMask = 2147483647;
114 | files = (
115 | );
116 | runOnlyForDeploymentPostprocessing = 0;
117 | };
118 | /* End PBXHeadersBuildPhase section */
119 |
120 | /* Begin PBXNativeTarget section */
121 | C2CC54581A71D8610084E87D /* ObserverSet */ = {
122 | isa = PBXNativeTarget;
123 | buildConfigurationList = C2CC546F1A71D8610084E87D /* Build configuration list for PBXNativeTarget "ObserverSet" */;
124 | buildPhases = (
125 | C2CC54541A71D8610084E87D /* Sources */,
126 | C2CC54551A71D8610084E87D /* Frameworks */,
127 | C2CC54561A71D8610084E87D /* Headers */,
128 | C2CC54571A71D8610084E87D /* Resources */,
129 | );
130 | buildRules = (
131 | );
132 | dependencies = (
133 | );
134 | name = ObserverSet;
135 | productName = ObserverSet;
136 | productReference = C2CC54591A71D8610084E87D /* ObserverSet.framework */;
137 | productType = "com.apple.product-type.framework";
138 | };
139 | C2CC54631A71D8610084E87D /* ObserverSetTests */ = {
140 | isa = PBXNativeTarget;
141 | buildConfigurationList = C2CC54721A71D8610084E87D /* Build configuration list for PBXNativeTarget "ObserverSetTests" */;
142 | buildPhases = (
143 | C2CC54601A71D8610084E87D /* Sources */,
144 | C2CC54611A71D8610084E87D /* Frameworks */,
145 | C2CC54621A71D8610084E87D /* Resources */,
146 | );
147 | buildRules = (
148 | );
149 | dependencies = (
150 | C2CC54671A71D8610084E87D /* PBXTargetDependency */,
151 | );
152 | name = ObserverSetTests;
153 | productName = ObserverSetTests;
154 | productReference = C2CC54641A71D8610084E87D /* ObserverSetTests.xctest */;
155 | productType = "com.apple.product-type.bundle.unit-test";
156 | };
157 | /* End PBXNativeTarget section */
158 |
159 | /* Begin PBXProject section */
160 | C2CC54501A71D8610084E87D /* Project object */ = {
161 | isa = PBXProject;
162 | attributes = {
163 | LastSwiftMigration = 0720;
164 | LastSwiftUpdateCheck = 0720;
165 | LastUpgradeCheck = 0720;
166 | ORGANIZATIONNAME = "Mike Ash";
167 | TargetAttributes = {
168 | C2CC54581A71D8610084E87D = {
169 | CreatedOnToolsVersion = 6.1.1;
170 | };
171 | C2CC54631A71D8610084E87D = {
172 | CreatedOnToolsVersion = 6.1.1;
173 | };
174 | };
175 | };
176 | buildConfigurationList = C2CC54531A71D8610084E87D /* Build configuration list for PBXProject "ObserverSet" */;
177 | compatibilityVersion = "Xcode 3.2";
178 | developmentRegion = English;
179 | hasScannedForEncodings = 0;
180 | knownRegions = (
181 | en,
182 | );
183 | mainGroup = C2CC544F1A71D8610084E87D;
184 | productRefGroup = C2CC545A1A71D8610084E87D /* Products */;
185 | projectDirPath = "";
186 | projectRoot = "";
187 | targets = (
188 | C2CC54581A71D8610084E87D /* ObserverSet */,
189 | C2CC54631A71D8610084E87D /* ObserverSetTests */,
190 | );
191 | };
192 | /* End PBXProject section */
193 |
194 | /* Begin PBXResourcesBuildPhase section */
195 | C2CC54571A71D8610084E87D /* Resources */ = {
196 | isa = PBXResourcesBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | );
200 | runOnlyForDeploymentPostprocessing = 0;
201 | };
202 | C2CC54621A71D8610084E87D /* Resources */ = {
203 | isa = PBXResourcesBuildPhase;
204 | buildActionMask = 2147483647;
205 | files = (
206 | );
207 | runOnlyForDeploymentPostprocessing = 0;
208 | };
209 | /* End PBXResourcesBuildPhase section */
210 |
211 | /* Begin PBXSourcesBuildPhase section */
212 | C2CC54541A71D8610084E87D /* Sources */ = {
213 | isa = PBXSourcesBuildPhase;
214 | buildActionMask = 2147483647;
215 | files = (
216 | C2CC54761A71D8FE0084E87D /* ObserverSet.swift in Sources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | C2CC54601A71D8610084E87D /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | C2CC546C1A71D8610084E87D /* ObserverSetTests.swift in Sources */,
225 | 8E904FD01C80206600383B20 /* CaptureSemanticsTests.swift in Sources */,
226 | );
227 | runOnlyForDeploymentPostprocessing = 0;
228 | };
229 | /* End PBXSourcesBuildPhase section */
230 |
231 | /* Begin PBXTargetDependency section */
232 | C2CC54671A71D8610084E87D /* PBXTargetDependency */ = {
233 | isa = PBXTargetDependency;
234 | target = C2CC54581A71D8610084E87D /* ObserverSet */;
235 | targetProxy = C2CC54661A71D8610084E87D /* PBXContainerItemProxy */;
236 | };
237 | /* End PBXTargetDependency section */
238 |
239 | /* Begin XCBuildConfiguration section */
240 | C2CC546D1A71D8610084E87D /* Debug */ = {
241 | isa = XCBuildConfiguration;
242 | buildSettings = {
243 | ALWAYS_SEARCH_USER_PATHS = NO;
244 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
245 | CLANG_CXX_LIBRARY = "libc++";
246 | CLANG_ENABLE_MODULES = YES;
247 | CLANG_ENABLE_OBJC_ARC = YES;
248 | CLANG_WARN_BOOL_CONVERSION = YES;
249 | CLANG_WARN_CONSTANT_CONVERSION = YES;
250 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
251 | CLANG_WARN_EMPTY_BODY = YES;
252 | CLANG_WARN_ENUM_CONVERSION = YES;
253 | CLANG_WARN_INT_CONVERSION = YES;
254 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
255 | CLANG_WARN_UNREACHABLE_CODE = YES;
256 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
257 | COPY_PHASE_STRIP = NO;
258 | CURRENT_PROJECT_VERSION = 1;
259 | ENABLE_STRICT_OBJC_MSGSEND = YES;
260 | ENABLE_TESTABILITY = YES;
261 | GCC_C_LANGUAGE_STANDARD = gnu99;
262 | GCC_DYNAMIC_NO_PIC = NO;
263 | GCC_OPTIMIZATION_LEVEL = 0;
264 | GCC_PREPROCESSOR_DEFINITIONS = (
265 | "DEBUG=1",
266 | "$(inherited)",
267 | );
268 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 | GCC_WARN_UNDECLARED_SELECTOR = YES;
272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 | GCC_WARN_UNUSED_FUNCTION = YES;
274 | GCC_WARN_UNUSED_VARIABLE = YES;
275 | MACOSX_DEPLOYMENT_TARGET = 10.10;
276 | MTL_ENABLE_DEBUG_INFO = YES;
277 | ONLY_ACTIVE_ARCH = YES;
278 | SDKROOT = macosx;
279 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
280 | VERSIONING_SYSTEM = "apple-generic";
281 | VERSION_INFO_PREFIX = "";
282 | };
283 | name = Debug;
284 | };
285 | C2CC546E1A71D8610084E87D /* Release */ = {
286 | isa = XCBuildConfiguration;
287 | buildSettings = {
288 | ALWAYS_SEARCH_USER_PATHS = NO;
289 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
290 | CLANG_CXX_LIBRARY = "libc++";
291 | CLANG_ENABLE_MODULES = YES;
292 | CLANG_ENABLE_OBJC_ARC = YES;
293 | CLANG_WARN_BOOL_CONVERSION = YES;
294 | CLANG_WARN_CONSTANT_CONVERSION = YES;
295 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
296 | CLANG_WARN_EMPTY_BODY = YES;
297 | CLANG_WARN_ENUM_CONVERSION = YES;
298 | CLANG_WARN_INT_CONVERSION = YES;
299 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
300 | CLANG_WARN_UNREACHABLE_CODE = YES;
301 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
302 | COPY_PHASE_STRIP = YES;
303 | CURRENT_PROJECT_VERSION = 1;
304 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
305 | ENABLE_NS_ASSERTIONS = NO;
306 | ENABLE_STRICT_OBJC_MSGSEND = YES;
307 | GCC_C_LANGUAGE_STANDARD = gnu99;
308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
310 | GCC_WARN_UNDECLARED_SELECTOR = YES;
311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
312 | GCC_WARN_UNUSED_FUNCTION = YES;
313 | GCC_WARN_UNUSED_VARIABLE = YES;
314 | MACOSX_DEPLOYMENT_TARGET = 10.10;
315 | MTL_ENABLE_DEBUG_INFO = NO;
316 | SDKROOT = macosx;
317 | VERSIONING_SYSTEM = "apple-generic";
318 | VERSION_INFO_PREFIX = "";
319 | };
320 | name = Release;
321 | };
322 | C2CC54701A71D8610084E87D /* Debug */ = {
323 | isa = XCBuildConfiguration;
324 | buildSettings = {
325 | CLANG_ENABLE_MODULES = YES;
326 | COMBINE_HIDPI_IMAGES = YES;
327 | DEFINES_MODULE = YES;
328 | DYLIB_COMPATIBILITY_VERSION = 1;
329 | DYLIB_CURRENT_VERSION = 1;
330 | DYLIB_INSTALL_NAME_BASE = "@rpath";
331 | FRAMEWORK_VERSION = A;
332 | INFOPLIST_FILE = ObserverSet/Info.plist;
333 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
334 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
335 | PRODUCT_BUNDLE_IDENTIFIER = "com.mikeash.$(PRODUCT_NAME:rfc1034identifier)";
336 | PRODUCT_NAME = "$(TARGET_NAME)";
337 | SKIP_INSTALL = YES;
338 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
339 | };
340 | name = Debug;
341 | };
342 | C2CC54711A71D8610084E87D /* Release */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | CLANG_ENABLE_MODULES = YES;
346 | COMBINE_HIDPI_IMAGES = YES;
347 | DEFINES_MODULE = YES;
348 | DYLIB_COMPATIBILITY_VERSION = 1;
349 | DYLIB_CURRENT_VERSION = 1;
350 | DYLIB_INSTALL_NAME_BASE = "@rpath";
351 | FRAMEWORK_VERSION = A;
352 | INFOPLIST_FILE = ObserverSet/Info.plist;
353 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
354 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
355 | PRODUCT_BUNDLE_IDENTIFIER = "com.mikeash.$(PRODUCT_NAME:rfc1034identifier)";
356 | PRODUCT_NAME = "$(TARGET_NAME)";
357 | SKIP_INSTALL = YES;
358 | };
359 | name = Release;
360 | };
361 | C2CC54731A71D8610084E87D /* Debug */ = {
362 | isa = XCBuildConfiguration;
363 | buildSettings = {
364 | COMBINE_HIDPI_IMAGES = YES;
365 | FRAMEWORK_SEARCH_PATHS = (
366 | "$(DEVELOPER_FRAMEWORKS_DIR)",
367 | "$(inherited)",
368 | );
369 | GCC_PREPROCESSOR_DEFINITIONS = (
370 | "DEBUG=1",
371 | "$(inherited)",
372 | );
373 | INFOPLIST_FILE = ObserverSetTests/Info.plist;
374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
375 | PRODUCT_BUNDLE_IDENTIFIER = "com.mikeash.$(PRODUCT_NAME:rfc1034identifier)";
376 | PRODUCT_NAME = "$(TARGET_NAME)";
377 | };
378 | name = Debug;
379 | };
380 | C2CC54741A71D8610084E87D /* Release */ = {
381 | isa = XCBuildConfiguration;
382 | buildSettings = {
383 | COMBINE_HIDPI_IMAGES = YES;
384 | FRAMEWORK_SEARCH_PATHS = (
385 | "$(DEVELOPER_FRAMEWORKS_DIR)",
386 | "$(inherited)",
387 | );
388 | INFOPLIST_FILE = ObserverSetTests/Info.plist;
389 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
390 | PRODUCT_BUNDLE_IDENTIFIER = "com.mikeash.$(PRODUCT_NAME:rfc1034identifier)";
391 | PRODUCT_NAME = "$(TARGET_NAME)";
392 | };
393 | name = Release;
394 | };
395 | /* End XCBuildConfiguration section */
396 |
397 | /* Begin XCConfigurationList section */
398 | C2CC54531A71D8610084E87D /* Build configuration list for PBXProject "ObserverSet" */ = {
399 | isa = XCConfigurationList;
400 | buildConfigurations = (
401 | C2CC546D1A71D8610084E87D /* Debug */,
402 | C2CC546E1A71D8610084E87D /* Release */,
403 | );
404 | defaultConfigurationIsVisible = 0;
405 | defaultConfigurationName = Release;
406 | };
407 | C2CC546F1A71D8610084E87D /* Build configuration list for PBXNativeTarget "ObserverSet" */ = {
408 | isa = XCConfigurationList;
409 | buildConfigurations = (
410 | C2CC54701A71D8610084E87D /* Debug */,
411 | C2CC54711A71D8610084E87D /* Release */,
412 | );
413 | defaultConfigurationIsVisible = 0;
414 | defaultConfigurationName = Release;
415 | };
416 | C2CC54721A71D8610084E87D /* Build configuration list for PBXNativeTarget "ObserverSetTests" */ = {
417 | isa = XCConfigurationList;
418 | buildConfigurations = (
419 | C2CC54731A71D8610084E87D /* Debug */,
420 | C2CC54741A71D8610084E87D /* Release */,
421 | );
422 | defaultConfigurationIsVisible = 0;
423 | defaultConfigurationName = Release;
424 | };
425 | /* End XCConfigurationList section */
426 | };
427 | rootObject = C2CC54501A71D8610084E87D /* Project object */;
428 | }
429 |
--------------------------------------------------------------------------------