[英]Comparing objects in Obj-C, why they don't match?
賞金公告
你好! 我開始懸賞這個問題,因為人們沒有閱讀整個問題,也沒有試圖理解問題的根源。 或者,不知道這里發生了什么。 需要更詳細的方法。。謝謝!
結束
當我使用自定義任務調用NSURLSession時,我將這些任務存儲在字典中。 當我收到代表回電時,我需要找到它的任務。 這是我的方法:
- (NSInteger)getOperationIdentifierForTask:(NSURLSessionTask*)task
{
for (NSString *key in self.operations)
{
HttpTaskOperation *value = [self.operations objectForKey:key];
if (value.task == task) return [key integerValue]; //**********
}
return 0;
}
它以前對我有效(肯定是iOS7),但現在這種比較永遠不會成功。 我還從本地人那里獲取了屏幕截圖,看到對象ID突出顯示。 是的,我不是C開發人員,所以可能與問題有關:)我認為這是由於指針問題引起的。
當執行帶有// *****的代碼行時-我找不到匹配項。 此函數始終返回0。
編輯:
似乎與代理相關的問題。 當我創建並存儲NSURLSession時,iOS實際上會返回NSProxy。 與NSUURLSessionTask相同。 這一切都是新事物嗎,鑒於您在當地人看到的東西,我該如何比較那些對象? 我需要獲取task._taskDelegate
但是它沒有公開。
目前尚不清楚如何向operations
中添加項目。
這行是誤導性的:
for (NSString *key in self.operations)
由於在調試跟蹤中,您的鍵似乎實際上是operations
NSNumbers。
為什么不嘗試使用taskIdentifier呢 ? 應該在會話中唯一地標識任務。
- (NSInteger)getOperationIdentifierForTask:(NSURLSessionTask*)task
{
NSNumber * value = self.operations[@(task.taskIdentifier)];
if( value == nil )
return 0;
return value.integerValue;
}
您不能在非原始對象上使用原始相等性檢查==
。 您應該使用isEqual:
在您的子類中重寫它,並比較要保證相等性所需的相同項的任何屬性。
在子類中執行以下操作:
-(BOOL)isEqual:(id)object{
if([object isKindOfClass:[YourSubClass class]]){
YourSubClass *otherObject = (YourSubClass*)object;
NSInteger currentDistinctiveNumber = [self.someDistinctiveProperty integerValue];
NSInteger otherDistinctiveNumber = [otherObject.someDistinctiveProperty integerValue];
if(currentDistinctiveNumber == otherDistinctiveNumber){
return YES;
}
}
return NO;
}
如果您確定它可以在iOS 7中使用,並且我在這里猜測 ,在轉換到iOS 9之前您沒有任何問題,我想說這個問題可能是由Apple的新App Transport Security引起的。
在iOS 9和OS X 10.11中,Apple引入了應用傳輸安全性(ATS),這是對應用程序網絡連接的低級限制。 這些限制中最明顯的一項是要求應用程序不再通過純HTTP建立連接; 相反,除非另有明確說明,否則操作系統將強制使用HTTPS。
從提供的屏幕截圖來看,您似乎指向的URL是基於http://
的URL,而不是https://
。 我說這是因為您的問題似乎始於HTTPTaskOperation
。
將以下字典添加到應用程序的.plist文件中:
這完全使蘋果的新安全性(ATS)失效
如果這是一個令人擔憂的問題,或者仍然無法解決問題,則需要調整例外以適應項目的需要。 查看先前的鏈接,或閱讀Apple的App Transport Security 文檔 。
。
〜添加〜
但是,如果您使用的是基於委托的實現,則事情開始變得相當繁瑣。 這是因為NSURLSession具有可理解的(但令人討厭的)功能,其中任務級委托是在會話級實現的。 (考慮一下:需要不同處理的兩個不同請求正在共享會話對象上調用相同的委托方法。Egad!)
可以在操作中包裝基於委托的NSURLSessionTask(...),但這涉及到一個笨拙的過程,即會話對象必須維護一個字典,該字典將任務標識符與任務操作對象交叉引用,並將這些任務委托方法傳遞給任務對象,然后使任務對象符合各種NSURLSessionTask委托協議。 這需要大量工作,因為NSURLSession在會話上未提供maxConcurrentOperationCount風格的功能(更不用說其他NSOperationQueue的優點了,例如依賴關系,完成塊等)。
Objective-C中的“ ==”運算符檢查兩個變量是否指向完全相同的對象。 如果您有2個包含相同數據的不同對象,則測試將失敗。
正如其他人所說,您應該為您的自定義子類實現isEqual方法,或者如果您沒有簡便的方法將子類/類添加到類中,則可以創建一個將兩個對象作為對象的全局函數。參數並返回BOOL,告訴您它們是否等效。
在objective-c測試中,'=='對對象的引用是否相等。 這意味着它將檢查兩個對象是否為同一對象,而不是它們的值是否相同。 嘗試使用對象isEqualTo:函數。 如果它是您自己的對象,請編寫一個isEqualTo:函數以測試該對象中某個值的相等性。
也許可以在存儲操作之前在NSURLSessionTask
的taskDescription
屬性中為每個任務存儲唯一的標識符,然后在以后使用該值進行比較。 該值應保持不變,從而避免在傳遞的對象之間進行指針比較。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.